2 The Miscellaneous Routines for TlsDxe driver.
4 Copyright (c) 2016 - 2017, 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
;
60 RecordHeaderIn
= NULL
;
61 TempRecordHeader
= NULL
;
67 // Calculate the size according to the fragment table.
69 for (Index
= 0; Index
< *FragmentCount
; Index
++) {
70 BufferInSize
+= (*FragmentTable
)[Index
].FragmentLength
;
74 // Allocate buffer for processing data.
76 BufferIn
= AllocateZeroPool (BufferInSize
);
77 if (BufferIn
== NULL
) {
78 Status
= EFI_OUT_OF_RESOURCES
;
83 // Copy all TLS plain record header and payload into BufferIn.
85 for (Index
= 0; Index
< *FragmentCount
; Index
++) {
87 (BufferIn
+ BytesCopied
),
88 (*FragmentTable
)[Index
].FragmentBuffer
,
89 (*FragmentTable
)[Index
].FragmentLength
91 BytesCopied
+= (*FragmentTable
)[Index
].FragmentLength
;
94 BufferOut
= AllocateZeroPool (MAX_BUFFER_SIZE
);
95 if (BufferOut
== NULL
) {
96 Status
= EFI_OUT_OF_RESOURCES
;
103 BufferInPtr
= BufferIn
;
104 TempRecordHeader
= (TLS_RECORD_HEADER
*) BufferOut
;
105 while ((UINTN
) BufferInPtr
< (UINTN
) BufferIn
+ BufferInSize
) {
106 RecordHeaderIn
= (TLS_RECORD_HEADER
*) BufferInPtr
;
108 if (RecordHeaderIn
->ContentType
!= TlsContentTypeApplicationData
) {
109 Status
= EFI_INVALID_PARAMETER
;
113 ThisPlainMessageSize
= RecordHeaderIn
->Length
;
115 TlsWrite (TlsInstance
->TlsConn
, (UINT8
*) (RecordHeaderIn
+ 1), ThisPlainMessageSize
);
117 Ret
= TlsCtrlTrafficOut (TlsInstance
->TlsConn
, (UINT8
*)(TempRecordHeader
), MAX_BUFFER_SIZE
- BufferOutSize
);
120 ThisMessageSize
= (UINT16
) Ret
;
123 // No data was successfully encrypted, continue to encrypt other messages.
125 DEBUG ((EFI_D_WARN
, "TlsEncryptPacket: No data read from TLS object.\n"));
130 BufferOutSize
+= ThisMessageSize
;
132 BufferInPtr
+= RECORD_HEADER_LEN
+ ThisPlainMessageSize
;
133 TempRecordHeader
+= ThisMessageSize
;
140 // The caller will be responsible to handle the original fragment table.
142 *FragmentTable
= AllocateZeroPool (sizeof (EFI_TLS_FRAGMENT_DATA
));
143 if (*FragmentTable
== NULL
) {
144 Status
= EFI_OUT_OF_RESOURCES
;
148 (*FragmentTable
)[0].FragmentBuffer
= BufferOut
;
149 (*FragmentTable
)[0].FragmentLength
= BufferOutSize
;
156 if (BufferIn
!= NULL
) {
161 if (BufferOut
!= NULL
) {
162 FreePool (BufferOut
);
170 Decrypt the message listed in fragment.
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.
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.
187 IN TLS_INSTANCE
*TlsInstance
,
188 IN OUT EFI_TLS_FRAGMENT_DATA
**FragmentTable
,
189 IN UINT32
*FragmentCount
198 TLS_RECORD_HEADER
*RecordHeaderIn
;
199 UINT16 ThisCipherMessageSize
;
200 TLS_RECORD_HEADER
*TempRecordHeader
;
201 UINT16 ThisPlainMessageSize
;
203 UINT32 BufferOutSize
;
206 Status
= EFI_SUCCESS
;
211 RecordHeaderIn
= NULL
;
212 TempRecordHeader
= NULL
;
218 // Calculate the size according to the fragment table.
220 for (Index
= 0; Index
< *FragmentCount
; Index
++) {
221 BufferInSize
+= (*FragmentTable
)[Index
].FragmentLength
;
225 // Allocate buffer for processing data
227 BufferIn
= AllocateZeroPool (BufferInSize
);
228 if (BufferIn
== NULL
) {
229 Status
= EFI_OUT_OF_RESOURCES
;
234 // Copy all TLS plain record header and payload to BufferIn
236 for (Index
= 0; Index
< *FragmentCount
; Index
++) {
238 (BufferIn
+ BytesCopied
),
239 (*FragmentTable
)[Index
].FragmentBuffer
,
240 (*FragmentTable
)[Index
].FragmentLength
242 BytesCopied
+= (*FragmentTable
)[Index
].FragmentLength
;
245 BufferOut
= AllocateZeroPool (MAX_BUFFER_SIZE
);
246 if (BufferOut
== NULL
) {
247 Status
= EFI_OUT_OF_RESOURCES
;
252 // Parsing buffer. Received packet may have multiple TLS record messages.
254 BufferInPtr
= BufferIn
;
255 TempRecordHeader
= (TLS_RECORD_HEADER
*) BufferOut
;
256 while ((UINTN
) BufferInPtr
< (UINTN
) BufferIn
+ BufferInSize
) {
257 RecordHeaderIn
= (TLS_RECORD_HEADER
*) BufferInPtr
;
259 if (RecordHeaderIn
->ContentType
!= TlsContentTypeApplicationData
) {
260 Status
= EFI_INVALID_PARAMETER
;
264 ThisCipherMessageSize
= NTOHS (RecordHeaderIn
->Length
);
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
;
274 Ret
= TlsRead (TlsInstance
->TlsConn
, (UINT8
*) (TempRecordHeader
+ 1), MAX_BUFFER_SIZE
- BufferOutSize
);
277 ThisPlainMessageSize
= (UINT16
) Ret
;
280 // No data was successfully decrypted, continue to decrypt other messages.
282 DEBUG ((EFI_D_WARN
, "TlsDecryptPacket: No data read from TLS object.\n"));
284 ThisPlainMessageSize
= 0;
287 CopyMem (TempRecordHeader
, RecordHeaderIn
, RECORD_HEADER_LEN
);
288 TempRecordHeader
->Length
= ThisPlainMessageSize
;
289 BufferOutSize
+= RECORD_HEADER_LEN
+ ThisPlainMessageSize
;
291 BufferInPtr
+= RECORD_HEADER_LEN
+ ThisCipherMessageSize
;
292 TempRecordHeader
+= RECORD_HEADER_LEN
+ ThisPlainMessageSize
;
299 // The caller will be responsible to handle the original fragment table
301 *FragmentTable
= AllocateZeroPool (sizeof (EFI_TLS_FRAGMENT_DATA
));
302 if (*FragmentTable
== NULL
) {
303 Status
= EFI_OUT_OF_RESOURCES
;
307 (*FragmentTable
)[0].FragmentBuffer
= BufferOut
;
308 (*FragmentTable
)[0].FragmentLength
= BufferOutSize
;
315 if (BufferIn
!= NULL
) {
320 if (BufferOut
!= NULL
) {
321 FreePool (BufferOut
);