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