1 /**************************************************************************/
2 /*                                                                        */
3 /*       Copyright (c) Microsoft Corporation. All rights reserved.        */
4 /*                                                                        */
5 /*       This software is licensed under the Microsoft Software License   */
6 /*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
7 /*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
8 /*       and in the root directory of this software.                      */
9 /*                                                                        */
10 /**************************************************************************/
11 
12 
13 /**************************************************************************/
14 /**************************************************************************/
15 /**                                                                       */
16 /** NetX Secure Component                                                 */
17 /**                                                                       */
18 /**    Datagram Transport Layer Security (DTLS)                           */
19 /**                                                                       */
20 /**************************************************************************/
21 /**************************************************************************/
22 
23 #define NX_SECURE_SOURCE_CODE
24 
25 #include "nx_secure_dtls.h"
26 
27 /**************************************************************************/
28 /*                                                                        */
29 /*  FUNCTION                                               RELEASE        */
30 /*                                                                        */
31 /*    _nx_secure_dtls_packet_allocate                     PORTABLE C      */
32 /*                                                           6.1          */
33 /*  AUTHOR                                                                */
34 /*                                                                        */
35 /*    Timothy Stapko, Microsoft Corporation                               */
36 /*                                                                        */
37 /*  DESCRIPTION                                                           */
38 /*                                                                        */
39 /*    This function allocates a packet for DTLS.                          */
40 /*                                                                        */
41 /*  INPUT                                                                 */
42 /*                                                                        */
43 /*    dtls_session                          DTLS control block            */
44 /*    pool_ptr                              Pool to allocate packet from  */
45 /*    packet_ptr                            Pointer to place allocated    */
46 /*                                            packet pointer              */
47 /*    wait_option                           Suspension option             */
48 /*                                                                        */
49 /*  OUTPUT                                                                */
50 /*                                                                        */
51 /*    status                                Completion status             */
52 /*                                                                        */
53 /*  CALLS                                                                 */
54 /*                                                                        */
55 /*    _nx_secure_tls_session_iv_size_get    Get IV size for this session. */
56 /*    nx_packet_allocate                    NetX Packet allocation call.  */
57 /*                                                                        */
58 /*  CALLED BY                                                             */
59 /*                                                                        */
60 /*    Application                                                         */
61 /*    _nx_secure_dtls_allocate_handshake_packet                           */
62 /*                                          Allocate DTLS handshake packet*/
63 /*    _nx_secure_dtls_client_handshake      DTLS client state machine     */
64 /*    _nx_secure_dtls_server_handshake      DTLS server state machine     */
65 /*    _nx_secure_dtls_session_end           Actual DTLS session end call. */
66 /*    _nx_secure_dtls_session_receive       Receive DTLS data             */
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 /*                                                                        */
76 /**************************************************************************/
_nx_secure_dtls_packet_allocate(NX_SECURE_DTLS_SESSION * dtls_session,NX_PACKET_POOL * pool_ptr,NX_PACKET ** packet_ptr,ULONG wait_option)77 UINT _nx_secure_dtls_packet_allocate(NX_SECURE_DTLS_SESSION *dtls_session, NX_PACKET_POOL *pool_ptr,
78                                      NX_PACKET **packet_ptr, ULONG wait_option)
79 {
80 #ifdef NX_SECURE_ENABLE_DTLS
81 UINT                   status;
82 ULONG                  packet_type;
83 USHORT                 iv_size;
84 NX_SECURE_TLS_SESSION *tls_session;
85 
86 
87     if (dtls_session -> nx_secure_dtls_remote_ip_address.nxd_ip_version == NX_IP_VERSION_V4)
88     {
89         packet_type = NX_IPv4_UDP_PACKET;
90     }
91     else
92     {
93         packet_type = NX_IPv6_UDP_PACKET;
94     }
95 
96 
97     status =  nx_packet_allocate(pool_ptr, packet_ptr, packet_type, wait_option);
98 
99     if (status != NX_SUCCESS)
100     {
101         return(NX_SECURE_TLS_ALLOCATE_PACKET_FAILED);
102     }
103 
104     if (((ULONG)((*packet_ptr) -> nx_packet_data_end) - (ULONG)((*packet_ptr) -> nx_packet_prepend_ptr)) <
105         (NX_SECURE_DTLS_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         return(NX_SECURE_TLS_PACKET_BUFFER_TOO_SMALL);
111     }
112 
113     /* Advance the packet prepend pointer past the record header. */
114     (*packet_ptr) -> nx_packet_prepend_ptr += NX_SECURE_DTLS_RECORD_HEADER_SIZE;
115 
116     /* Get a pointer to TLS state. */
117     tls_session = &dtls_session -> nx_secure_dtls_tls_session;
118 
119     /* If TLS session is active, allocate space for the IV that precedes the data in
120        certain ciphersuites. */
121     if (tls_session -> nx_secure_tls_local_session_active)
122     {
123         /* Get the size of the IV used by the session cipher. */
124         status = _nx_secure_tls_session_iv_size_get(tls_session, &iv_size);
125 
126         if (status != NX_SUCCESS)
127         {
128             return(status);
129         }
130 
131         if ((iv_size + 2u) > ((ULONG)((*packet_ptr) -> nx_packet_data_end) - (ULONG)((*packet_ptr) -> nx_packet_prepend_ptr)))
132         {
133 
134             /* Packet buffer is too small to hold IV. */
135             nx_packet_release(*packet_ptr);
136             *packet_ptr = NX_NULL;
137             return(NX_SECURE_TLS_PACKET_BUFFER_TOO_SMALL);
138         }
139 
140         /* Don't do anything if no IV is required. */
141         if (iv_size > 0)
142         {
143             /* Pre-allocate space for the session cipher IV and clear it out. */
144             NX_SECURE_MEMSET((*packet_ptr) -> nx_packet_prepend_ptr, 0, iv_size);
145             (*packet_ptr) -> nx_packet_prepend_ptr += iv_size;
146         }
147     }
148 
149     /* Make sure our append and prepend pointers are pointing to the same thing - when
150        the packet is allocated it is "empty" from a user perspective. */
151     (*packet_ptr) -> nx_packet_append_ptr = (*packet_ptr) -> nx_packet_prepend_ptr;
152     (*packet_ptr) -> nx_packet_length = 0;
153 
154     return(NX_SECURE_TLS_SUCCESS);
155 #else
156     NX_PARAMETER_NOT_USED(dtls_session);
157     NX_PARAMETER_NOT_USED(pool_ptr);
158     NX_PARAMETER_NOT_USED(packet_ptr);
159     NX_PARAMETER_NOT_USED(wait_option);
160 
161     return(NX_NOT_SUPPORTED);
162 #endif /* NX_SECURE_ENABLE_DTLS */
163 }
164 
165