2 The Miscellaneous Routines for TlsDxe driver.
4 Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
19 Encrypt the message listed in fragment.
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.
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.
36 IN TLS_INSTANCE
*TlsInstance
,
37 IN OUT EFI_TLS_FRAGMENT_DATA
**FragmentTable
,
38 IN UINT32
*FragmentCount
47 TLS_RECORD_HEADER
*RecordHeaderIn
;
48 UINT16 ThisPlainMessageSize
;
49 TLS_RECORD_HEADER
*TempRecordHeader
;
50 UINT16 ThisMessageSize
;
61 RecordHeaderIn
= NULL
;
62 TempRecordHeader
= NULL
;
69 // Calculate the size according to the fragment table.
71 for (Index
= 0; Index
< *FragmentCount
; Index
++) {
72 BufferInSize
+= (*FragmentTable
)[Index
].FragmentLength
;
76 // Allocate buffer for processing data.
78 BufferIn
= AllocateZeroPool (BufferInSize
);
79 if (BufferIn
== NULL
) {
80 Status
= EFI_OUT_OF_RESOURCES
;
85 // Copy all TLS plain record header and payload into BufferIn.
87 for (Index
= 0; Index
< *FragmentCount
; Index
++) {
89 (BufferIn
+ BytesCopied
),
90 (*FragmentTable
)[Index
].FragmentBuffer
,
91 (*FragmentTable
)[Index
].FragmentLength
93 BytesCopied
+= (*FragmentTable
)[Index
].FragmentLength
;
97 // Count TLS record number.
99 BufferInPtr
= BufferIn
;
100 while ((UINTN
) BufferInPtr
< (UINTN
) BufferIn
+ BufferInSize
) {
101 RecordHeaderIn
= (TLS_RECORD_HEADER
*) BufferInPtr
;
102 if (RecordHeaderIn
->ContentType
!= TlsContentTypeApplicationData
|| RecordHeaderIn
->Length
> TLS_PLAINTEXT_RECORD_MAX_PAYLOAD_LENGTH
) {
103 Status
= EFI_INVALID_PARAMETER
;
106 BufferInPtr
+= TLS_RECORD_HEADER_LENGTH
+ RecordHeaderIn
->Length
;
111 // Allocate enough buffer to hold TLS Ciphertext.
113 BufferOut
= AllocateZeroPool (RecordCount
* (TLS_RECORD_HEADER_LENGTH
+ TLS_CIPHERTEXT_RECORD_MAX_PAYLOAD_LENGTH
));
114 if (BufferOut
== NULL
) {
115 Status
= EFI_OUT_OF_RESOURCES
;
120 // Parsing buffer. Received packet may have multiple TLS record messages.
122 BufferInPtr
= BufferIn
;
123 TempRecordHeader
= (TLS_RECORD_HEADER
*) BufferOut
;
124 while ((UINTN
) BufferInPtr
< (UINTN
) BufferIn
+ BufferInSize
) {
125 RecordHeaderIn
= (TLS_RECORD_HEADER
*) BufferInPtr
;
127 ThisPlainMessageSize
= RecordHeaderIn
->Length
;
129 TlsWrite (TlsInstance
->TlsConn
, (UINT8
*) (RecordHeaderIn
+ 1), ThisPlainMessageSize
);
131 Ret
= TlsCtrlTrafficOut (TlsInstance
->TlsConn
, (UINT8
*)(TempRecordHeader
), TLS_RECORD_HEADER_LENGTH
+ TLS_CIPHERTEXT_RECORD_MAX_PAYLOAD_LENGTH
);
134 ThisMessageSize
= (UINT16
) Ret
;
137 // No data was successfully encrypted, continue to encrypt other messages.
139 DEBUG ((EFI_D_WARN
, "TlsEncryptPacket: No data read from TLS object.\n"));
144 BufferOutSize
+= ThisMessageSize
;
146 BufferInPtr
+= TLS_RECORD_HEADER_LENGTH
+ ThisPlainMessageSize
;
147 TempRecordHeader
+= ThisMessageSize
;
154 // The caller will be responsible to handle the original fragment table.
156 *FragmentTable
= AllocateZeroPool (sizeof (EFI_TLS_FRAGMENT_DATA
));
157 if (*FragmentTable
== NULL
) {
158 Status
= EFI_OUT_OF_RESOURCES
;
162 (*FragmentTable
)[0].FragmentBuffer
= BufferOut
;
163 (*FragmentTable
)[0].FragmentLength
= BufferOutSize
;
170 if (BufferIn
!= NULL
) {
175 if (BufferOut
!= NULL
) {
176 FreePool (BufferOut
);
184 Decrypt the message listed in fragment.
186 @param[in] TlsInstance The pointer to the TLS instance.
187 @param[in, out] FragmentTable Pointer to a list of fragment.
188 On input these fragments contain the TLS header and
189 cipher text TLS payload;
190 On output these fragments contain the TLS header and
191 plain text TLS payload.
192 @param[in] FragmentCount Number of fragment.
194 @retval EFI_SUCCESS The operation completed successfully.
195 @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
196 @retval EFI_ABORTED TLS session state is incorrect.
197 @retval Others Other errors as indicated.
201 IN TLS_INSTANCE
*TlsInstance
,
202 IN OUT EFI_TLS_FRAGMENT_DATA
**FragmentTable
,
203 IN UINT32
*FragmentCount
212 TLS_RECORD_HEADER
*RecordHeaderIn
;
213 UINT16 ThisCipherMessageSize
;
214 TLS_RECORD_HEADER
*TempRecordHeader
;
215 UINT16 ThisPlainMessageSize
;
217 UINT32 BufferOutSize
;
221 Status
= EFI_SUCCESS
;
226 RecordHeaderIn
= NULL
;
227 TempRecordHeader
= NULL
;
234 // Calculate the size according to the fragment table.
236 for (Index
= 0; Index
< *FragmentCount
; Index
++) {
237 BufferInSize
+= (*FragmentTable
)[Index
].FragmentLength
;
241 // Allocate buffer for processing data
243 BufferIn
= AllocateZeroPool (BufferInSize
);
244 if (BufferIn
== NULL
) {
245 Status
= EFI_OUT_OF_RESOURCES
;
250 // Copy all TLS plain record header and payload to BufferIn
252 for (Index
= 0; Index
< *FragmentCount
; Index
++) {
254 (BufferIn
+ BytesCopied
),
255 (*FragmentTable
)[Index
].FragmentBuffer
,
256 (*FragmentTable
)[Index
].FragmentLength
258 BytesCopied
+= (*FragmentTable
)[Index
].FragmentLength
;
262 // Count TLS record number.
264 BufferInPtr
= BufferIn
;
265 while ((UINTN
) BufferInPtr
< (UINTN
) BufferIn
+ BufferInSize
) {
266 RecordHeaderIn
= (TLS_RECORD_HEADER
*) BufferInPtr
;
267 if (RecordHeaderIn
->ContentType
!= TlsContentTypeApplicationData
|| NTOHS (RecordHeaderIn
->Length
) > TLS_CIPHERTEXT_RECORD_MAX_PAYLOAD_LENGTH
) {
268 Status
= EFI_INVALID_PARAMETER
;
271 BufferInPtr
+= TLS_RECORD_HEADER_LENGTH
+ NTOHS (RecordHeaderIn
->Length
);
276 // Allocate enough buffer to hold TLS Plaintext.
278 BufferOut
= AllocateZeroPool (RecordCount
* (TLS_RECORD_HEADER_LENGTH
+ TLS_PLAINTEXT_RECORD_MAX_PAYLOAD_LENGTH
));
279 if (BufferOut
== NULL
) {
280 Status
= EFI_OUT_OF_RESOURCES
;
285 // Parsing buffer. Received packet may have multiple TLS record messages.
287 BufferInPtr
= BufferIn
;
288 TempRecordHeader
= (TLS_RECORD_HEADER
*) BufferOut
;
289 while ((UINTN
) BufferInPtr
< (UINTN
) BufferIn
+ BufferInSize
) {
290 RecordHeaderIn
= (TLS_RECORD_HEADER
*) BufferInPtr
;
292 ThisCipherMessageSize
= NTOHS (RecordHeaderIn
->Length
);
294 Ret
= TlsCtrlTrafficIn (TlsInstance
->TlsConn
, (UINT8
*) (RecordHeaderIn
), TLS_RECORD_HEADER_LENGTH
+ ThisCipherMessageSize
);
295 if (Ret
!= TLS_RECORD_HEADER_LENGTH
+ ThisCipherMessageSize
) {
296 TlsInstance
->TlsSessionState
= EfiTlsSessionError
;
297 Status
= EFI_ABORTED
;
302 Ret
= TlsRead (TlsInstance
->TlsConn
, (UINT8
*) (TempRecordHeader
+ 1), TLS_PLAINTEXT_RECORD_MAX_PAYLOAD_LENGTH
);
305 ThisPlainMessageSize
= (UINT16
) Ret
;
308 // No data was successfully decrypted, continue to decrypt other messages.
310 DEBUG ((EFI_D_WARN
, "TlsDecryptPacket: No data read from TLS object.\n"));
312 ThisPlainMessageSize
= 0;
315 CopyMem (TempRecordHeader
, RecordHeaderIn
, TLS_RECORD_HEADER_LENGTH
);
316 TempRecordHeader
->Length
= ThisPlainMessageSize
;
317 BufferOutSize
+= TLS_RECORD_HEADER_LENGTH
+ ThisPlainMessageSize
;
319 BufferInPtr
+= TLS_RECORD_HEADER_LENGTH
+ ThisCipherMessageSize
;
320 TempRecordHeader
+= TLS_RECORD_HEADER_LENGTH
+ ThisPlainMessageSize
;
327 // The caller will be responsible to handle the original fragment table
329 *FragmentTable
= AllocateZeroPool (sizeof (EFI_TLS_FRAGMENT_DATA
));
330 if (*FragmentTable
== NULL
) {
331 Status
= EFI_OUT_OF_RESOURCES
;
335 (*FragmentTable
)[0].FragmentBuffer
= BufferOut
;
336 (*FragmentTable
)[0].FragmentLength
= BufferOutSize
;
343 if (BufferIn
!= NULL
) {
348 if (BufferOut
!= NULL
) {
349 FreePool (BufferOut
);