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 /**************************************************************************/
27 /* */
28 /* FUNCTION RELEASE */
29 /* */
30 /* _nx_secure_tls_packet_allocate PORTABLE C */
31 /* 6.1.10 */
32 /* AUTHOR */
33 /* */
34 /* Timothy Stapko, Microsoft Corporation */
35 /* */
36 /* DESCRIPTION */
37 /* */
38 /* This function allocates a packet for TLS application. */
39 /* */
40 /* INPUT */
41 /* */
42 /* tls_session TLS control block */
43 /* pool_ptr Pool to allocate packet from */
44 /* packet_ptr Pointer to place allocated */
45 /* packet pointer */
46 /* wait_option Suspension option */
47 /* */
48 /* OUTPUT */
49 /* */
50 /* status Completion status */
51 /* */
52 /* CALLS */
53 /* */
54 /* nx_packet_allocate NetX Packet allocation call */
55 /* _nx_secure_tls_session_iv_size_get Get IV size for this session */
56 /* */
57 /* CALLED BY */
58 /* */
59 /* Application */
60 /* _nx_secure_tls_allocate_handshake_packet */
61 /* Allocate TLS packet */
62 /* _nx_secure_tls_client_handshake TLS client state machine */
63 /* _nx_secure_tls_server_handshake TLS server state machine */
64 /* _nx_secure_tls_session_end End of a session */
65 /* _nx_secure_tls_session_receive_records */
66 /* Receive TLS records */
67 /* */
68 /* RELEASE HISTORY */
69 /* */
70 /* DATE NAME DESCRIPTION */
71 /* */
72 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
73 /* 09-30-2020 Timothy Stapko Modified comment(s), */
74 /* resulting in version 6.1 */
75 /* 01-31-2022 Timothy Stapko Modified comment(s), and */
76 /* fixed the packet leak, */
77 /* resulting in version 6.1.10 */
78 /* */
79 /**************************************************************************/
_nx_secure_tls_packet_allocate(NX_SECURE_TLS_SESSION * tls_session,NX_PACKET_POOL * pool_ptr,NX_PACKET ** packet_ptr,ULONG wait_option)80 UINT _nx_secure_tls_packet_allocate(NX_SECURE_TLS_SESSION *tls_session, NX_PACKET_POOL *pool_ptr,
81 NX_PACKET **packet_ptr, ULONG wait_option)
82 {
83 UINT status;
84 ULONG packet_type;
85 USHORT iv_size;
86
87 if (tls_session -> nx_secure_tls_tcp_socket -> nx_tcp_socket_connect_ip.nxd_ip_version == NX_IP_VERSION_V4)
88 {
89 packet_type = NX_IPv4_TCP_PACKET;
90 }
91 else
92 {
93 packet_type = NX_IPv6_TCP_PACKET;
94 }
95
96 status = nx_packet_allocate(pool_ptr, packet_ptr, packet_type, wait_option);
97
98
99 if (status != NX_SUCCESS)
100 {
101 return(status);
102 }
103
104 if (((ULONG)((*packet_ptr) -> nx_packet_data_end) - (ULONG)((*packet_ptr) -> nx_packet_prepend_ptr)) <
105 (NX_SECURE_TLS_RECORD_HEADER_SIZE + 2u)) /* At least 2 bytes for Alert message. */
106 {
107
108 /* Packet buffer is too small. */
109 nx_packet_release(*packet_ptr);
110 *packet_ptr = NX_NULL;
111 return(NX_SECURE_TLS_PACKET_BUFFER_TOO_SMALL);
112 }
113
114 /* Advance the packet prepend pointer past the record header. */
115 (*packet_ptr) -> nx_packet_prepend_ptr += NX_SECURE_TLS_RECORD_HEADER_SIZE;
116
117 /* If TLS session is active, allocate space for the IV that precedes the data in
118 certain ciphersuites. */
119 if (tls_session -> nx_secure_tls_local_session_active)
120 {
121 /* Get the size of the IV used by the session cipher. */
122 status = _nx_secure_tls_session_iv_size_get(tls_session, &iv_size);
123
124 if (status != NX_SUCCESS)
125 {
126
127 /* Fail to get the size of the IV. */
128 nx_packet_release(*packet_ptr);
129 *packet_ptr = NX_NULL;
130 return(status);
131 }
132
133 if ((iv_size + 2u) > ((ULONG)((*packet_ptr) -> nx_packet_data_end) - (ULONG)((*packet_ptr) -> nx_packet_prepend_ptr)))
134 {
135
136 /* Packet buffer is too small to hold IV. */
137 nx_packet_release(*packet_ptr);
138 *packet_ptr = NX_NULL;
139 return(NX_SECURE_TLS_PACKET_BUFFER_TOO_SMALL);
140 }
141
142 /* Don't do anything if no IV is required. */
143 if (iv_size > 0)
144 {
145 /* Pre-allocate space for the session cipher IV and clear it out. */
146 NX_SECURE_MEMSET((*packet_ptr) -> nx_packet_prepend_ptr, 0, iv_size);
147 (*packet_ptr) -> nx_packet_prepend_ptr += iv_size;
148 }
149 }
150
151 /* Make sure our append and prepend pointers are pointing to the same thing - when
152 the packet is allocated it is "empty" from a user perspective. */
153 (*packet_ptr) -> nx_packet_append_ptr = (*packet_ptr) -> nx_packet_prepend_ptr;
154 (*packet_ptr) -> nx_packet_length = 0;
155
156
157 return(NX_SECURE_TLS_SUCCESS);
158 }
159
160