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