1 /* This test concentrates on DTLS connections. */
2
3 #include "nx_api.h"
4 #include "nx_secure_dtls_api.h"
5 #include "test_ca_cert.c"
6 #include "test_device_cert.c"
7
8 extern VOID test_control_return(UINT status);
9
10
11 #if !defined(NX_SECURE_TLS_CLIENT_DISABLED) && !defined(NX_SECURE_TLS_SERVER_DISABLED) && defined(NX_SECURE_ENABLE_DTLS)
12 #define NUM_PACKETS 24
13 #define PACKET_SIZE 1536
14 #define PACKET_POOL_SIZE (NUM_PACKETS * (PACKET_SIZE + sizeof(NX_PACKET)))
15 #define THREAD_STACK_SIZE 1024
16 #define ARP_CACHE_SIZE 1024
17 #define BUFFER_SIZE 64
18 #define METADATA_SIZE 16000
19 #define CERT_BUFFER_SIZE (2048 + sizeof(NX_SECURE_X509_CERT))
20 #define PSK "simple_psk"
21 #define PSK_IDENTITY "psk_indentity"
22 #define PSK_HINT "psk_hint"
23 #define SERVER_PORT 4433
24
25
26 /* Define the ThreadX and NetX object control blocks... */
27
28 static TX_THREAD thread_0;
29 static TX_THREAD thread_1;
30 static NX_PACKET_POOL pool_0;
31 static NX_IP ip_0;
32 static UINT error_counter;
33
34 static NX_UDP_SOCKET client_socket_0;
35 static NX_SECURE_DTLS_SESSION dtls_client_session_0;
36 static NX_SECURE_DTLS_SERVER dtls_server_0;
37 static NX_SECURE_X509_CERT client_trusted_ca;
38 static NX_SECURE_X509_CERT client_remote_cert;
39 static NX_SECURE_X509_CERT server_local_certificate;
40 extern const NX_SECURE_TLS_CRYPTO
41 nx_crypto_tls_ciphers;
42
43 static ULONG pool_0_memory[PACKET_POOL_SIZE / sizeof(ULONG)];
44 static ULONG thread_0_stack[THREAD_STACK_SIZE / sizeof(ULONG)];
45 static ULONG thread_1_stack[THREAD_STACK_SIZE / sizeof(ULONG)];
46 static ULONG ip_0_stack[THREAD_STACK_SIZE / sizeof(ULONG)];
47 static ULONG arp_cache[ARP_CACHE_SIZE];
48 static UCHAR client_metadata[METADATA_SIZE];
49 static UCHAR server_metadata[METADATA_SIZE];
50 static UCHAR client_cert_buffer[CERT_BUFFER_SIZE];
51
52 static UCHAR request_buffer[BUFFER_SIZE];
53 static UCHAR response_buffer[BUFFER_SIZE];
54 static UCHAR tls_packet_buffer[2][4000];
55 static UINT drop_packet_sequence[] =
56 {
57 0, /* ClientHello */
58 2, /* ClientHello_Verify */
59 7, /* Certificate */
60 };
61 static UINT packet_sequence;
62 static UINT drop_index;
63
64 /* Session buffer for DTLS server. Must be equal to the size of NX_SECURE_DTLS_SESSION times the
65 number of desired DTLS sessions. */
66 static UCHAR server_session_buffer[sizeof(NX_SECURE_DTLS_SESSION)];
67
68 /* Define thread prototypes. */
69
70 static VOID ntest_0_entry(ULONG thread_input);
71 static VOID ntest_1_entry(ULONG thread_input);
72 extern VOID _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req);
73 extern VOID _nx_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr);
74
75 static TX_SEMAPHORE semaphore_receive;
76 static TX_SEMAPHORE semaphore_connect;
77
78
79 /* Define what the initial system looks like. */
80
81
ERROR_COUNTER()82 static VOID ERROR_COUNTER()
83 {
84 error_counter++;
85 }
86
87 #ifdef CTEST
88 void test_application_define(void *first_unused_memory);
test_application_define(void * first_unused_memory)89 void test_application_define(void *first_unused_memory)
90 #else
91 VOID nx_secure_dtls_retransmit_test_application_define(void *first_unused_memory)
92 #endif
93 {
94 UINT status;
95 CHAR *pointer;
96
97
98 error_counter = 0;
99 packet_sequence = 0;
100 drop_index = 0;
101
102
103 /* Setup the working pointer. */
104 pointer = (CHAR *) first_unused_memory;
105
106 /* Create the server thread. */
107 tx_thread_create(&thread_0, "thread 0", ntest_0_entry, 0,
108 thread_0_stack, sizeof(thread_0_stack),
109 7, 7, TX_NO_TIME_SLICE, TX_AUTO_START);
110
111 /* Create the client thread. */
112 tx_thread_create(&thread_1, "thread 1", ntest_1_entry, 0,
113 thread_1_stack, sizeof(thread_1_stack),
114 8, 8, TX_NO_TIME_SLICE, TX_AUTO_START);
115
116 tx_semaphore_create(&semaphore_receive, "semaphore receive", 0);
117 tx_semaphore_create(&semaphore_connect, "semaphore connect", 0);
118
119 /* Initialize the NetX system. */
120 nx_system_initialize();
121
122 /* Create a packet pool. */
123 status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", PACKET_SIZE,
124 pool_0_memory, PACKET_POOL_SIZE);
125 if (status)
126 {
127 ERROR_COUNTER();
128 }
129
130 /* Create an IP instance. */
131 status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL,
132 &pool_0, _nx_ram_network_driver_1500,
133 ip_0_stack, sizeof(ip_0_stack), 1);
134 if (status)
135 {
136 ERROR_COUNTER();
137 }
138
139 /* Enable ARP and supply ARP cache memory for IP Instance 0. */
140 status = nx_arp_enable(&ip_0, (VOID *)arp_cache, sizeof(arp_cache));
141 if (status)
142 {
143 ERROR_COUNTER();
144 }
145
146 /* Enable UDP traffic. */
147 status = nx_udp_enable(&ip_0);
148 if (status)
149 {
150 ERROR_COUNTER();
151 }
152
153 nx_secure_tls_initialize();
154 nx_secure_dtls_initialize();
155 }
156
udp_packet_receive(NX_IP * ip_ptr,NX_PACKET * packet_ptr)157 static VOID udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr)
158 {
159 if ((drop_index < sizeof(drop_packet_sequence) / sizeof(UINT)) &&
160 (packet_sequence++ == drop_packet_sequence[drop_index]))
161 {
162 drop_index++;
163 nx_packet_release(packet_ptr);
164 return;
165 }
166 _nx_udp_packet_receive(ip_ptr, packet_ptr);
167 }
168
client_dtls_setup(NX_SECURE_DTLS_SESSION * dtls_session_ptr)169 static VOID client_dtls_setup(NX_SECURE_DTLS_SESSION *dtls_session_ptr)
170 {
171 UINT status;
172
173 status = nx_secure_dtls_session_create(dtls_session_ptr,
174 &nx_crypto_tls_ciphers,
175 client_metadata,
176 sizeof(client_metadata), tls_packet_buffer[0],
177 sizeof(tls_packet_buffer[0]), 1, client_cert_buffer,
178 sizeof(client_cert_buffer));
179 if (status)
180 {
181 ERROR_COUNTER();
182 }
183
184 status = nx_secure_x509_certificate_initialize(&client_trusted_ca,
185 test_ca_cert_der,
186 test_ca_cert_der_len, NX_NULL, 0, NULL, 0, NX_SECURE_X509_KEY_TYPE_NONE);
187 if (status)
188 {
189 ERROR_COUNTER();
190 }
191
192 status = nx_secure_dtls_session_trusted_certificate_add(dtls_session_ptr, &client_trusted_ca, 1);
193 if (status)
194 {
195 ERROR_COUNTER();
196 }
197
198
199 #if defined(NX_SECURE_ENABLE_PSK_CIPHERSUITES) || defined(NX_SECURE_ENABLE_ECJPAKE_CIPHERSUITE)
200 /* For PSK ciphersuites, add a PSK and identity hint. */
201 nx_secure_dtls_psk_add(dtls_session_ptr, PSK, strlen(PSK),
202 PSK_IDENTITY, strlen(PSK_IDENTITY), PSK_HINT, strlen(PSK_HINT));
203 #endif
204 }
205
206 /* Notification flags for DTLS server connect/receive. */
207 static UINT server_connect_notify_flag = NX_FALSE;
208 static UINT server_receive_notify_flag = NX_FALSE;
209
210 NX_SECURE_DTLS_SESSION *connect_session;
211 NX_SECURE_DTLS_SESSION *receive_session;
212
213 /* Connect notify callback for DTLS server - notifies the application thread that
214 a DTLS connection is ready to kickoff a handshake. */
server_connect_notify(NX_SECURE_DTLS_SESSION * dtls_session,NXD_ADDRESS * ip_address,UINT port)215 static UINT server_connect_notify(NX_SECURE_DTLS_SESSION *dtls_session, NXD_ADDRESS *ip_address, UINT port)
216 {
217 /* Drop connections if one is in progress. Better way would be to have
218 * an array of pointers to DTLS sessions and check the port/IP address
219 * to see if it's an existing connection. Application thread then loops
220 * through array servicing each session.
221 */
222 if (server_connect_notify_flag == NX_FALSE)
223 {
224 server_connect_notify_flag = NX_TRUE;
225 connect_session = dtls_session;
226 tx_semaphore_put(&semaphore_connect);
227 }
228
229 return(NX_SUCCESS);
230 }
231
232 /* Receive notify callback for DTLS server - notifies the application thread that
233 we have received a DTLS record over an established DTLS session. */
server_receive_notify(NX_SECURE_DTLS_SESSION * dtls_session)234 static UINT server_receive_notify(NX_SECURE_DTLS_SESSION *dtls_session)
235 {
236
237 /* Drop records if more come in while processing one. Better would be to
238 service each session in a queue. */
239 if (server_receive_notify_flag == NX_FALSE)
240 {
241 server_receive_notify_flag = NX_TRUE;
242 receive_session = dtls_session;
243 tx_semaphore_put(&semaphore_receive);
244 }
245
246 return(NX_SUCCESS);
247 }
248
server_dtls_setup(NX_SECURE_DTLS_SERVER * dtls_server_ptr)249 static VOID server_dtls_setup(NX_SECURE_DTLS_SERVER *dtls_server_ptr)
250 {
251 UINT status;
252
253 status = nx_secure_dtls_server_create(dtls_server_ptr, &ip_0, SERVER_PORT, NX_IP_PERIODIC_RATE,
254 server_session_buffer, sizeof(server_session_buffer),
255 &nx_crypto_tls_ciphers, server_metadata, sizeof(server_metadata),
256 tls_packet_buffer[1], sizeof(tls_packet_buffer[1]),
257 server_connect_notify, server_receive_notify);
258 if (status)
259 {
260 ERROR_COUNTER();
261 }
262
263 memset(&server_local_certificate, 0, sizeof(server_local_certificate));
264 status = nx_secure_x509_certificate_initialize(&server_local_certificate,
265 test_device_cert_der, test_device_cert_der_len,
266 NX_NULL, 0, test_device_cert_key_der,
267 test_device_cert_key_der_len, NX_SECURE_X509_KEY_TYPE_RSA_PKCS1_DER);
268 if (status)
269 {
270 ERROR_COUNTER();
271 }
272
273 status = nx_secure_dtls_server_local_certificate_add(dtls_server_ptr, &server_local_certificate, 1);
274 if (status)
275 {
276 ERROR_COUNTER();
277 }
278 }
279
ntest_0_entry(ULONG thread_input)280 static void ntest_0_entry(ULONG thread_input)
281 {
282 UINT status;
283 ULONG response_length;
284 NX_PACKET *packet_ptr;
285
286 /* Print out test information banner. */
287 printf("NetX Secure Test: DTLS Retransmit Test...............................");
288
289 ip_0.nx_ip_udp_packet_receive = udp_packet_receive;
290
291 server_dtls_setup(&dtls_server_0);
292
293 /* Start DTLS session. */
294 status = nx_secure_dtls_server_start(&dtls_server_0);
295 if (status)
296 {
297 printf("Error in starting DTLS server: 0x%02X\n", status);
298 ERROR_COUNTER();
299 }
300
301 /* Wait for connection attempt. */
302 tx_semaphore_get(&semaphore_connect, NX_WAIT_FOREVER);
303 server_connect_notify_flag = NX_FALSE;
304
305 status = nx_secure_dtls_server_session_start(connect_session, NX_WAIT_FOREVER);
306
307 if(status)
308 {
309 printf("Error in establishing DTLS server session: 0x%02X\n", status);
310 ERROR_COUNTER();
311 }
312
313 /* Wait for records to be received. */
314 tx_semaphore_get(&semaphore_receive, NX_WAIT_FOREVER);
315
316 status = nx_secure_dtls_session_receive(receive_session,
317 &packet_ptr, NX_WAIT_FOREVER);
318 if (status)
319 {
320 printf("Error in DTLS server session receive: 0x%02X\n", status);
321 ERROR_COUNTER();
322 }
323
324 nx_packet_data_retrieve(packet_ptr, response_buffer, &response_length);
325 nx_packet_release(packet_ptr);
326 if ((response_length != sizeof(request_buffer)) ||
327 memcmp(request_buffer, response_buffer, response_length))
328 {
329 ERROR_COUNTER();
330 }
331
332 /* Clear the receive flag. */
333 server_receive_notify_flag = NX_FALSE;
334
335 nx_secure_dtls_session_end(&dtls_server_0.nx_dtls_server_sessions[0], NX_NO_WAIT);
336
337 tx_thread_suspend(&thread_0);
338
339 /* Shutdown DTLS server. */
340 nx_secure_dtls_server_stop(&dtls_server_0);
341
342 /* Delete server. */
343 nx_secure_dtls_server_delete(&dtls_server_0);
344
345 if (error_counter)
346 {
347 printf("ERROR!\n");
348 test_control_return(1);
349 }
350 else
351 {
352 printf("SUCCESS!\n");
353 test_control_return(0);
354 }
355 }
356
ntest_1_entry(ULONG thread_input)357 static void ntest_1_entry(ULONG thread_input)
358 {
359 UINT i;
360 UINT status;
361 NX_PACKET *packet_ptr;
362 NXD_ADDRESS server_address;
363
364 for (i = 0; i < sizeof(request_buffer); i++)
365 {
366 request_buffer[i] = i;
367 response_buffer[i] = 0;
368 }
369
370 server_address.nxd_ip_version = NX_IP_VERSION_V4;
371 server_address.nxd_ip_address.v4 = IP_ADDRESS(127, 0, 0, 1);
372
373 /* Create UDP socket. */
374 status = nx_udp_socket_create(&ip_0, &client_socket_0, "Client socket", NX_IP_NORMAL,
375 NX_DONT_FRAGMENT, 0x80, 5);
376 if (status)
377 {
378 ERROR_COUNTER();
379 }
380
381 status = nx_udp_socket_bind(&client_socket_0, NX_ANY_PORT, NX_NO_WAIT);
382 if (status)
383 {
384 ERROR_COUNTER();
385 }
386
387 client_dtls_setup(&dtls_client_session_0);
388
389 /* Start DTLS session. */
390 status = nx_secure_dtls_client_session_start(&dtls_client_session_0, &client_socket_0, &server_address, SERVER_PORT, NX_WAIT_FOREVER);
391 if (status)
392 {
393 ERROR_COUNTER();
394 }
395
396 /* Prepare packet to send. */
397 status = nx_packet_allocate(&pool_0, &packet_ptr, NX_UDP_PACKET, NX_NO_WAIT);
398 if (status)
399 {
400 ERROR_COUNTER();
401 }
402
403 packet_ptr -> nx_packet_prepend_ptr += NX_SECURE_DTLS_RECORD_HEADER_SIZE;
404 packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr;
405
406 status = nx_packet_data_append(packet_ptr, request_buffer, sizeof(request_buffer),
407 &pool_0, NX_NO_WAIT);
408 if (status)
409 {
410 ERROR_COUNTER();
411 }
412
413 /* Send the packet. */
414 status = nx_secure_dtls_client_session_send(&dtls_client_session_0, packet_ptr);
415 if (status)
416 {
417 ERROR_COUNTER();
418 }
419
420 nx_secure_dtls_session_end(&dtls_client_session_0, NX_NO_WAIT);
421
422 nx_secure_dtls_session_delete(&dtls_client_session_0);
423
424 nx_udp_socket_unbind(&client_socket_0);
425
426 nx_udp_socket_delete(&client_socket_0);
427
428 tx_thread_resume(&thread_0);
429 }
430 #else
431 #ifdef CTEST
432 void test_application_define(void *first_unused_memory);
test_application_define(void * first_unused_memory)433 void test_application_define(void *first_unused_memory)
434 #else
435 VOID nx_secure_dtls_retransmit_test_application_define(void *first_unused_memory)
436 #endif
437 {
438
439 /* Print out test information banner. */
440 printf("NetX Secure Test: DTLS Retransmit Test...............................N/A\n");
441 test_control_return(3);
442 }
443 #endif
444