1 /***************************************************************************
2 * Copyright (c) 2024 Microsoft Corporation
3 *
4 * This program and the accompanying materials are made available under the
5 * terms of the MIT License which is available at
6 * https://opensource.org/licenses/MIT.
7 *
8 * SPDX-License-Identifier: MIT
9 **************************************************************************/
10
11
12 /**************************************************************************/
13 /**************************************************************************/
14 /** */
15 /** NetX Secure Component */
16 /** */
17 /** Transport Layer Security (TLS) */
18 /** */
19 /**************************************************************************/
20 /**************************************************************************/
21
22 #define NX_SECURE_SOURCE_CODE
23
24 #include "nx_secure_tls.h"
25
26 static VOID _nx_secure_tls_packet_trim(NX_PACKET *packet_ptr);
27
28 /**************************************************************************/
29 /* */
30 /* FUNCTION RELEASE */
31 /* */
32 /* _nx_secure_tls_process_record PORTABLE C */
33 /* 6.2.1 */
34 /* AUTHOR */
35 /* */
36 /* Timothy Stapko, Microsoft Corporation */
37 /* */
38 /* DESCRIPTION */
39 /* */
40 /* This function processes a single TLS record, handling both */
41 /* handshake and application records. When multiple records are */
42 /* received in a single lower-level network packet (e.g. TCP), the */
43 /* "record_offset" parameter is used to offset into the packet buffer. */
44 /* */
45 /* INPUT */
46 /* */
47 /* tls_session Pointer to TLS control block */
48 /* packet_ptr NX_PACKET containing a record */
49 /* bytes_processed Return for size of packet */
50 /* wait_option Control timeout options */
51 /* */
52 /* OUTPUT */
53 /* */
54 /* status Completion status */
55 /* */
56 /* CALLS */
57 /* */
58 /* _nx_secure_tls_client_handshake TLS Client state machine */
59 /* _nx_secure_tls_process_changecipherspec */
60 /* Process ChangeCipherSpec */
61 /* _nx_secure_tls_process_header Process record header */
62 /* _nx_secure_tls_record_payload_decrypt Decrypt record data */
63 /* _nx_secure_tls_server_handshake TLS Server state machine */
64 /* _nx_secure_tls_verify_mac Verify record MAC checksum */
65 /* nx_packet_allocate NetX Packet allocation call */
66 /* nx_packet_data_append Append data to packet */
67 /* nx_packet_data_extract_offset Extract data from NX_PACKET */
68 /* _nx_secure_tls_packet_trim Trim TLS packet */
69 /* tx_mutex_get Get protection mutex */
70 /* tx_mutex_put Put protection mutex */
71 /* */
72 /* CALLED BY */
73 /* */
74 /* _nx_secure_tls_session_receive_records */
75 /* Receive TLS records */
76 /* */
77 /* RELEASE HISTORY */
78 /* */
79 /* DATE NAME DESCRIPTION */
80 /* */
81 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
82 /* 09-30-2020 Timothy Stapko Modified comment(s), */
83 /* supported chained packet, */
84 /* fixed compiler warnings, */
85 /* resulting in version 6.1 */
86 /* 02-02-2021 Timothy Stapko Modified comment(s), added */
87 /* support for fragmented TLS */
88 /* Handshake messages, */
89 /* resulting in version 6.1.4 */
90 /* 08-02-2021 Timothy Stapko Modified comment(s), checked */
91 /* TLS state before processing,*/
92 /* resulting in version 6.1.8 */
93 /* 10-15-2021 Timothy Stapko Modified comment(s), fixed */
94 /* TLS 1.3 compile issue, */
95 /* resulting in version 6.1.9 */
96 /* 04-25-2022 Yuxin Zhou Modified comment(s), */
97 /* removed unnecessary code, */
98 /* resulting in version 6.1.11 */
99 /* 07-29-2022 Yuxin Zhou Modified comment(s), */
100 /* checked seq number overflow,*/
101 /* improved buffer length */
102 /* verification, */
103 /* resulting in version 6.1.12 */
104 /* 03-08-2023 Tiejun Zhou Modified comment(s), and */
105 /* corrected data cleanup, */
106 /* resulting in version 6.2.1 */
107 /* */
108 /**************************************************************************/
_nx_secure_tls_process_record(NX_SECURE_TLS_SESSION * tls_session,NX_PACKET * packet_ptr,ULONG * bytes_processed,ULONG wait_option)109 UINT _nx_secure_tls_process_record(NX_SECURE_TLS_SESSION *tls_session, NX_PACKET *packet_ptr,
110 ULONG *bytes_processed, ULONG wait_option)
111 {
112 UINT status;
113 UINT error_status;
114 USHORT header_length;
115 UCHAR header_data[NX_SECURE_TLS_RECORD_HEADER_SIZE] = {0}; /* DTLS record header is larger than TLS. Allocate enough space for both. */
116 USHORT message_type;
117 UINT message_length;
118 ULONG bytes_copied;
119 UCHAR *packet_data = NX_NULL;
120 ULONG record_offset = 0;
121 ULONG record_offset_next = 0;
122 NX_PACKET *decrypted_packet;
123
124 /* Basic state machine:
125 * 1. Process header, which will set the state and return some data.
126 * 2. Advance the packet pointer by the size of the header (returned by header processing)
127 * and process the record.
128 * 3. Take any actions necessary based on state.
129 *
130 *
131 * For reading TLS records from TCP packets we have two cases to worry about:
132 * 1. Multiple records per packet
133 * - Multiple TLS records are packed into a single packet.
134 * - Loop below continues to process records until queue is emptied
135 * 2. Multiple packets per record
136 * - Header or payload may span multiple chained packets
137 * - If we have less than a complete header, return NX_CONTINUE to read more bytes from TCP socket
138 * - If we have a complete header, process the header - this may happen multiple times
139 * if we returned NX_CONTINUE due to having an incomplete payload.
140 * - After processing the header, check to see if the entire payload (length from header) has
141 * been read from the socket into the queue. If incomplete, return NX_CONTINUE.
142 * - If the payload is complete, process it in the state machine (decrypt if necessary first)
143 * and update the record_offset and bytes_processed values accordingly.
144 */
145
146 status = NX_CONTINUE;
147 *bytes_processed = 0;
148
149 /* Make sure the TLS socket is not closed. */
150 if (tls_session -> nx_secure_tls_socket_type == NX_SECURE_TLS_SESSION_TYPE_NONE)
151 {
152
153 /* Session already closed. Release the packet. */
154 if (packet_ptr != NX_NULL)
155 {
156 nx_packet_release(packet_ptr);
157 }
158 return(NX_SECURE_TLS_INVALID_STATE);
159 }
160
161 /* Process the packet. */
162 if (packet_ptr != NX_NULL)
163 {
164 if (packet_ptr -> nx_packet_last == NX_NULL)
165 {
166
167 /* The logic below requires nx_packet_last is set which is always TRUE
168 for chained packets coming from NetX. However, this packet is not chained
169 so set the nx_packet_last pointer to itself. */
170 packet_ptr -> nx_packet_last = packet_ptr;
171 }
172
173 /* Chain the packet. */
174 if (tls_session -> nx_secure_record_queue_header == NX_NULL)
175 {
176 tls_session -> nx_secure_record_queue_header = packet_ptr;
177 }
178 else
179 {
180
181 /* Link current packet. */
182 tls_session -> nx_secure_record_queue_header -> nx_packet_last -> nx_packet_next = packet_ptr;
183 tls_session -> nx_secure_record_queue_header -> nx_packet_last = packet_ptr -> nx_packet_last;
184 tls_session -> nx_secure_record_queue_header -> nx_packet_length += packet_ptr -> nx_packet_length;
185 }
186 }
187
188 /* Reset nx_secure_tls_packet_buffer_bytes_copied if there is no fragmented message to be processed. */
189 if (tls_session->nx_secure_tls_handshake_record_fragment_state == NX_SECURE_TLS_HANDSHAKE_NO_FRAGMENT)
190 {
191 tls_session->nx_secure_tls_packet_buffer_bytes_copied = 0;
192 }
193
194 /* Get packet from record queue. */
195 packet_ptr = tls_session -> nx_secure_record_queue_header;
196
197 /* Process multiple records per packet. */
198 while (status == NX_CONTINUE)
199 {
200
201 /* Make sure the decrypted packet is NULL. */
202 if (tls_session -> nx_secure_record_decrypted_packet)
203 {
204 nx_secure_tls_packet_release(tls_session -> nx_secure_record_decrypted_packet);
205 tls_session -> nx_secure_record_decrypted_packet = NX_NULL;
206 }
207 decrypted_packet = NX_NULL;
208
209 /* Retrieve the saved record offset when more TCP packet is received for this one record. */
210 if (tls_session -> nx_secure_tls_record_offset)
211 {
212 record_offset = tls_session -> nx_secure_tls_record_offset;
213 tls_session -> nx_secure_tls_record_offset = 0;
214 *bytes_processed = tls_session -> nx_secure_tls_bytes_processed;
215 tls_session -> nx_secure_tls_bytes_processed = 0;
216 }
217
218 /* Process the TLS record header, which will set the state. */
219 status = _nx_secure_tls_process_header(tls_session, packet_ptr, record_offset, &message_type, &message_length, header_data, &header_length);
220
221 if (status != NX_SECURE_TLS_SUCCESS)
222 {
223 return(status);
224 }
225
226 /* Ignore empty records. */
227 if (message_length == 0)
228 {
229
230 /* Update the number of bytes we processed. */
231 *bytes_processed += (ULONG)header_length;
232 return(NX_SUCCESS);
233 }
234
235 /* Is the entire payload of the current record received? */
236 if ((header_length + record_offset + message_length) > packet_ptr -> nx_packet_length)
237 {
238
239 /* Wait more TCP packets for this one record, save record_offset and bytes_processed for next record processing. */
240 tls_session -> nx_secure_tls_record_offset = record_offset;
241 tls_session -> nx_secure_tls_bytes_processed = *bytes_processed;
242 return(NX_CONTINUE);
243 }
244
245 /* Update the number of bytes we processed. */
246 *bytes_processed += (ULONG)header_length + message_length;
247 tls_session -> nx_secure_tls_bytes_processed = *bytes_processed;
248 record_offset += (ULONG)header_length;
249 record_offset_next = record_offset + message_length;
250
251 /* Check for active encryption of incoming records. If encrypted, decrypt before further processing. */
252 if (tls_session -> nx_secure_tls_remote_session_active
253 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
254 && (!tls_session -> nx_secure_tls_1_3 || message_type == NX_SECURE_TLS_APPLICATION_DATA)
255 #endif
256 )
257 {
258
259 /* Check the record length. */
260 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
261 if (tls_session -> nx_secure_tls_1_3)
262 {
263 if (message_length > NX_SECURE_TLS_MAX_CIPHERTEXT_LENGTH_1_3)
264 {
265 return(NX_SECURE_TLS_RECORD_OVERFLOW);
266 }
267 }
268 else
269 #endif
270 {
271 if (message_length > NX_SECURE_TLS_MAX_CIPHERTEXT_LENGTH)
272 {
273 return(NX_SECURE_TLS_RECORD_OVERFLOW);
274 }
275 }
276
277 /* Decrypt the record data. */
278 status = _nx_secure_tls_record_payload_decrypt(tls_session, packet_ptr, record_offset,
279 message_length, &decrypted_packet,
280 tls_session -> nx_secure_tls_remote_sequence_number,
281 (UCHAR)message_type, wait_option);
282
283 /* Set the error status to something appropriate. */
284 error_status = NX_SECURE_TLS_SUCCESS;
285
286 /* Check the MAC hash if we were able to decrypt the record. */
287 if (status != NX_SECURE_TLS_SUCCESS)
288 {
289 /* Save off the error status so we can return it after the mac check. */
290 error_status = status;
291 }
292 else
293 {
294
295 /* Record it so it can be release in case it is not returned to user application. */
296 tls_session -> nx_secure_record_decrypted_packet = decrypted_packet;
297 message_length = decrypted_packet -> nx_packet_length;
298 }
299
300 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
301 /* TLS 1.3 uses AEAD for all authentication and encryption. Therefore
302 the MAC verification is only needed for older TLS versions. */
303 if(tls_session->nx_secure_tls_1_3)
304 {
305
306 if (status == NX_SECURE_TLS_SUCCESS)
307 {
308
309 /* In TLS 1.3, encrypted records have a single byte at the
310 record that contains the message type (e.g. application data,
311 ect.), which is now the ACTUAL message type. */
312 status = nx_packet_data_extract_offset(decrypted_packet,
313 decrypted_packet -> nx_packet_length - 1,
314 &message_type, 1, &bytes_copied);
315 if (status || (bytes_copied != 1))
316 {
317 error_status = NX_SECURE_TLS_INVALID_PACKET;
318 }
319
320 /* Remove the content type byte from the data length to process. */
321 message_length = message_length - 1;
322
323 /* Adjust packet length. */
324 decrypted_packet -> nx_packet_length = message_length;
325
326 /* Increment the sequence number. This is done in the MAC verify
327 step for 1.2 and earlier, but AEAD includes the MAC so we don't
328 check the MAC and need to increment here. */
329 if ((tls_session -> nx_secure_tls_remote_sequence_number[0] + 1) == 0)
330 {
331 /* Check for overflow of the 32-bit unsigned number. */
332 tls_session -> nx_secure_tls_remote_sequence_number[1]++;
333
334 if (tls_session -> nx_secure_tls_remote_sequence_number[1] == 0)
335 {
336
337 /* Check for overflow of the 64-bit unsigned number. As it should not reach here
338 in practical, we return a general error to prevent overflow theoretically. */
339 return(NX_NOT_SUCCESSFUL);
340 }
341 }
342 tls_session -> nx_secure_tls_remote_sequence_number[0]++;
343 }
344 }
345 else
346 #endif
347 {
348 /* Verify the hash MAC in the decrypted record. */
349 if (status)
350 {
351
352 /* !!! NOTE - the MAC check MUST always be performed regardless of the error state of
353 the payload decryption operation. Skipping the MAC check on padding failures
354 could enable a timing-based attack allowing an attacker to determine whether
355 padding was valid or not, causing an information leak. */
356 status = _nx_secure_tls_verify_mac(tls_session, header_data, header_length, packet_ptr, record_offset, &message_length);
357 }
358 else
359 {
360 status = _nx_secure_tls_verify_mac(tls_session, header_data, header_length, decrypted_packet, 0, &message_length);
361
362 if (status == NX_SECURE_TLS_SUCCESS)
363 {
364
365 /* Adjust packet length. */
366 decrypted_packet -> nx_packet_length = message_length;
367 }
368 }
369 }
370
371 /* Check to see if decryption or verification failed. */
372 if(error_status != NX_SECURE_TLS_SUCCESS)
373 {
374 /* Decryption failed. */
375 return(error_status);
376 }
377
378 if (status != NX_SECURE_TLS_SUCCESS)
379 {
380 /* MAC verification failed. */
381 return(status);
382 }
383
384 if (message_length > NX_SECURE_TLS_MAX_PLAINTEXT_LENGTH)
385 {
386 return(NX_SECURE_TLS_RECORD_OVERFLOW);
387 }
388
389 /* Trim packet. */
390 _nx_secure_tls_packet_trim(decrypted_packet);
391 }
392
393 if (message_type != NX_SECURE_TLS_APPLICATION_DATA)
394 {
395
396 /* For message other than application data, extract to packet buffer to make sure all data are in contiguous memory. */
397 /* Check available area of buffer. */
398 packet_data = tls_session -> nx_secure_tls_packet_buffer;
399 if (tls_session->nx_secure_tls_packet_buffer_bytes_copied + message_length > tls_session -> nx_secure_tls_packet_buffer_size)
400 {
401 return(NX_SECURE_TLS_PACKET_BUFFER_TOO_SMALL);
402 }
403
404 if (decrypted_packet == NX_NULL)
405 {
406 status = nx_packet_data_extract_offset(packet_ptr, record_offset,
407 tls_session -> nx_secure_tls_packet_buffer + tls_session->nx_secure_tls_packet_buffer_bytes_copied,
408 message_length, &bytes_copied);
409 }
410 else
411 {
412 status = nx_packet_data_extract_offset(decrypted_packet, 0,
413 tls_session -> nx_secure_tls_packet_buffer + tls_session->nx_secure_tls_packet_buffer_bytes_copied,
414 message_length, &bytes_copied);
415 }
416
417 if (status)
418 {
419 return(NX_SECURE_TLS_INVALID_PACKET);
420 }
421
422 tls_session -> nx_secure_tls_packet_buffer_bytes_copied += bytes_copied;
423
424 /* fragment is assembled, or continue to process another message in the same record, or need to read a new TCP packet. */
425 if (tls_session->nx_secure_tls_handshake_record_fragment_state == NX_SECURE_TLS_HANDSHAKE_RECEIVED_FRAGMENT)
426 {
427
428 if (tls_session -> nx_secure_tls_packet_buffer_bytes_copied > tls_session->nx_secure_tls_handshake_record_expected_length)
429 {
430 return(NX_SECURE_TLS_INVALID_PACKET);
431 }
432 /* All fragments are received and copied to tls_session -> nx_secure_tls_packet_buffer. */
433 else if (tls_session -> nx_secure_tls_packet_buffer_bytes_copied == tls_session->nx_secure_tls_handshake_record_expected_length)
434 {
435 tls_session->nx_secure_tls_handshake_record_fragment_state = NX_SECURE_TLS_HANDSHAKE_NO_FRAGMENT;
436 message_length = tls_session->nx_secure_tls_handshake_record_expected_length;
437 tls_session->nx_secure_tls_handshake_record_expected_length = 0;
438 }
439 else
440 {
441 /* process another message in the same record. */
442 record_offset += message_length;
443 status = NX_CONTINUE;
444 continue;
445 }
446 }
447 }
448
449 switch (message_type)
450 {
451 case NX_SECURE_TLS_CHANGE_CIPHER_SPEC:
452 /* Received a ChangeCipherSpec message - from now on all messages from remote host
453 will be encrypted using the session keys. */
454 _nx_secure_tls_process_changecipherspec(tls_session, packet_data, message_length);
455
456 break;
457 case NX_SECURE_TLS_ALERT:
458
459 if (message_length < 2)
460 {
461 status = NX_SECURE_TLS_INCORRECT_MESSAGE_LENGTH;
462 break;
463 }
464
465 /* We have received an alert. Check what the alert was and take appropriate action. */
466 /* The alert level is the first octet in the alert. The alert number is the second. */
467 if(packet_data[0] == NX_SECURE_TLS_ALERT_LEVEL_FATAL)
468 {
469 /* If we receive a fatal alert, clear all session keys. */
470 _nx_secure_tls_session_reset(tls_session);
471 }
472
473 /* Save off the alert level and value for the application to access. */
474 tls_session->nx_secure_tls_received_alert_level = packet_data[0];
475 tls_session->nx_secure_tls_received_alert_value = packet_data[1];
476 /* We have received an alert. Check what the alert was and take appropriate action. */
477 status = NX_SECURE_TLS_ALERT_RECEIVED;
478 break;
479 case NX_SECURE_TLS_HANDSHAKE:
480 #if (NX_SECURE_TLS_TLS_1_3_ENABLED) && !defined(NX_SECURE_TLS_CLIENT_DISABLED)
481 /* TLS 1.3 can send post-handshake messages with TLS HANDSHAKE record type. Process those separately. */
482 if(tls_session->nx_secure_tls_1_3 && tls_session -> nx_secure_tls_client_state == NX_SECURE_TLS_CLIENT_STATE_HANDSHAKE_FINISHED)
483 {
484 /* Process post-handshake messages. */
485 status = NX_SECURE_TLS_POST_HANDSHAKE_RECEIVED;
486 break;
487 }
488 #endif /* (NX_SECURE_TLS_TLS_1_3_ENABLED) */
489
490 #ifndef NX_SECURE_TLS_SERVER_DISABLED
491 /* The socket is a TLS server, so process incoming handshake messages in that context. */
492 if (tls_session -> nx_secure_tls_socket_type == NX_SECURE_TLS_SESSION_TYPE_SERVER)
493 {
494 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
495 if(tls_session->nx_secure_tls_1_3)
496 {
497 status = _nx_secure_tls_1_3_server_handshake(tls_session, packet_data, message_length, wait_option);
498
499 if ((status == NX_SUCCESS) && (tls_session -> nx_secure_tls_1_3 == NX_FALSE))
500 {
501
502 /* Negotiate a version of TLS prior to TLS 1.3. */
503 /* Handle the ClientHello packet by legacy routine. */
504 status = _nx_secure_tls_server_handshake(tls_session, packet_data, message_length, wait_option);
505 }
506 }
507 else
508 #endif
509 {
510 status = _nx_secure_tls_server_handshake(tls_session, packet_data, message_length, wait_option);
511 }
512 }
513 #endif
514
515
516 #ifndef NX_SECURE_TLS_CLIENT_DISABLED
517 /* The socket is a TLS client, so process incoming handshake messages in that context. */
518 if (tls_session -> nx_secure_tls_socket_type == NX_SECURE_TLS_SESSION_TYPE_CLIENT)
519 {
520 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
521 if(tls_session->nx_secure_tls_1_3)
522 {
523 status = _nx_secure_tls_1_3_client_handshake(tls_session, packet_data, message_length, wait_option);
524 if ((status == NX_SUCCESS) && (tls_session -> nx_secure_tls_1_3 == NX_FALSE))
525 {
526
527 /* Server negotiates a version of TLS prior to TLS 1.3. */
528 #ifdef NX_SECURE_TLS_DISABLE_PROTOCOL_VERSION_DOWNGRADE
529 /* Protocol version downgrade is disabled. Return error status. */
530 status = NX_SECURE_TLS_UNSUPPORTED_TLS_VERSION;
531 #else
532 /* Handle the ServerHello packet by legacy routine. */
533 _nx_secure_tls_handshake_hash_init(tls_session);
534 status = _nx_secure_tls_client_handshake(tls_session, packet_data, message_length, wait_option);
535 #endif /* NX_SECURE_TLS_DISABLE_PROTOCOL_VERSION_DOWNGRADE */
536 }
537 }
538 else
539 #endif
540 {
541 status = _nx_secure_tls_client_handshake(tls_session, packet_data, message_length, wait_option);
542 }
543
544 }
545
546 #endif
547
548 if (status == NX_SECURE_TLS_HANDSHAKE_FRAGMENT_RECEIVED)
549 {
550 /* Update record_offset.*/
551 record_offset = record_offset_next;
552
553 /* Check if reaching the end of this TCP packet. */
554 if (record_offset == packet_ptr -> nx_packet_length)
555 {
556 /* Wait more TCP packets for this one record, save record_offset and bytes_processed for next record processing. */
557 tls_session -> nx_secure_tls_record_offset = record_offset;
558 tls_session -> nx_secure_tls_bytes_processed = *bytes_processed;
559 return(NX_CONTINUE);
560 }
561 else
562 {
563 /* Did not reach the end, continue to process this packet. */
564 status = NX_CONTINUE;
565 }
566 }
567
568 break;
569 case NX_SECURE_TLS_APPLICATION_DATA:
570 /* The remote host is sending application data records now. Pass decrypted data back
571 to the networking API for the application to process. */
572
573 /* First, check for 0-length records. These can be sent but are internal to TLS so tell the
574 caller to continue receiving. 0-length records are sent as part of the BEAST attack
575 mitigation by some TLS implementations (notably OpenSSL). */
576 if (message_length == 0)
577 {
578 record_offset = record_offset_next;
579 status = NX_CONTINUE;
580 }
581 else
582 {
583 status = NX_SECURE_TLS_SUCCESS;
584 }
585 break;
586 default:
587 /* An unrecognized message was received, likely an error, possibly an attack. */
588 status = NX_SECURE_TLS_UNRECOGNIZED_MESSAGE_TYPE;
589 break;
590 }
591
592 #ifdef NX_SECURE_KEY_CLEAR
593 if ((message_type != NX_SECURE_TLS_APPLICATION_DATA) &&
594 (status != NX_CONTINUE))
595 {
596 NX_SECURE_MEMSET(packet_data, 0, message_length);
597 }
598 #endif /* NX_SECURE_KEY_CLEAR */
599 }
600
601 return(status);
602 }
603
604 /**************************************************************************/
605 /* */
606 /* FUNCTION RELEASE */
607 /* */
608 /* _nx_secure_tls_packet_trim PORTABLE C */
609 /* 6.1 */
610 /* AUTHOR */
611 /* */
612 /* Timothy Stapko, Microsoft Corporation */
613 /* */
614 /* DESCRIPTION */
615 /* */
616 /* This function trims TLS packet after decryption and hash verify. */
617 /* */
618 /* INPUT */
619 /* */
620 /* packet_ptr NX_PACKET containing a record */
621 /* */
622 /* OUTPUT */
623 /* */
624 /* status Completion status */
625 /* */
626 /* CALLS */
627 /* */
628 /* nx_secure_tls_packet_release Release packet */
629 /* */
630 /* CALLED BY */
631 /* */
632 /* _nx_secure_tls_process_record Process TLS records */
633 /* */
634 /* RELEASE HISTORY */
635 /* */
636 /* DATE NAME DESCRIPTION */
637 /* */
638 /* 09-30-2020 Timothy Stapko Initial Version 6.1 */
639 /* */
640 /**************************************************************************/
_nx_secure_tls_packet_trim(NX_PACKET * packet_ptr)641 static VOID _nx_secure_tls_packet_trim(NX_PACKET *packet_ptr)
642 {
643 ULONG payload_length;
644 ULONG message_length = packet_ptr -> nx_packet_length;
645 NX_PACKET *current_ptr;
646
647 if (message_length == 0)
648 {
649
650 /* Make sure the head packet is not released when the length is zero. */
651 if (packet_ptr -> nx_packet_next)
652 {
653
654 /* Release packet if remaining data are in chained packet. */
655 nx_secure_tls_packet_release(packet_ptr -> nx_packet_next);
656 packet_ptr -> nx_packet_next = NX_NULL;
657 packet_ptr -> nx_packet_last = packet_ptr;
658 }
659 packet_ptr -> nx_packet_prepend_ptr = packet_ptr -> nx_packet_data_start;
660 packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_data_start;
661 return;
662 }
663
664 for (current_ptr = packet_ptr; current_ptr; current_ptr = current_ptr -> nx_packet_next)
665 {
666 payload_length = (ULONG)(current_ptr -> nx_packet_append_ptr - current_ptr -> nx_packet_prepend_ptr);
667 if (message_length < payload_length)
668 {
669
670 /* Trim data from this packet. */
671 current_ptr -> nx_packet_append_ptr = current_ptr -> nx_packet_prepend_ptr + message_length;
672 if (current_ptr -> nx_packet_next)
673 {
674
675 /* Release packet if remaining data are in chained packet. */
676 nx_secure_tls_packet_release(current_ptr -> nx_packet_next);
677 current_ptr -> nx_packet_next = NX_NULL;
678 packet_ptr -> nx_packet_last = current_ptr;
679 }
680 break;
681 }
682 message_length -= (ULONG)(current_ptr -> nx_packet_append_ptr - current_ptr -> nx_packet_prepend_ptr);
683 }
684 }
685