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 #ifdef NX_SECURE_ENABLE_DTLS
29
30
31 /**************************************************************************/
32 /* */
33 /* FUNCTION RELEASE */
34 /* */
35 /* _nx_secure_dtls_server_handshake PORTABLE C */
36 /* 6.1.12 */
37 /* AUTHOR */
38 /* */
39 /* Timothy Stapko, Microsoft Corporation */
40 /* */
41 /* DESCRIPTION */
42 /* */
43 /* This function runs the DTLS Server mode state machine. It processes */
44 /* an incoming handshake record and takes appropriate action to */
45 /* advance the DTLS Server handshake. */
46 /* */
47 /* INPUT */
48 /* */
49 /* dtls_session TLS control block */
50 /* packet_buffer Pointer into record buffer */
51 /* data_length Length of data */
52 /* wait_option Controls timeout actions */
53 /* */
54 /* OUTPUT */
55 /* */
56 /* status Completion status */
57 /* */
58 /* CALLS */
59 /* */
60 /* _nx_secure_dtls_allocate_handshake_packet */
61 /* Allocate DTLS handshake packet*/
62 /* _nx_secure_dtls_packet_allocate Allocate internal DTLS packet */
63 /* _nx_secure_dtls_process_clienthello Process ClientHello */
64 /* _nx_secure_dtls_process_handshake_header */
65 /* Process handshake header */
66 /* _nx_secure_dtls_retransmit_queue_flush */
67 /* Flush retransmit queue */
68 /* _nx_secure_dtls_send_handshake_record Send DTLS handshake record */
69 /* _nx_secure_dtls_send_helloverifyrequest */
70 /* Send DTLS HelloVerifyRequest */
71 /* _nx_secure_dtls_send_record Send DTLS records */
72 /* _nx_secure_dtls_send_serverhello Send DTLS ServerHello */
73 /* _nx_secure_tls_generate_keys Generate session keys */
74 /* _nx_secure_tls_handshake_hash_init Initialize Finished hash */
75 /* _nx_secure_tls_handshake_hash_update Update Finished hash */
76 /* _nx_secure_tls_process_client_key_exchange */
77 /* Process key exchange */
78 /* _nx_secure_tls_process_finished Process Finished message */
79 /* _nx_secure_tls_send_certificate Send TLS certificate */
80 /* _nx_secure_tls_send_changecipherspec Send ChangeCipherSpec */
81 /* _nx_secure_tls_send_finished Send Finished message */
82 /* _nx_secure_tls_send_server_key_exchange */
83 /* Send ServerKeyExchange */
84 /* _nx_secure_tls_session_keys_set Set session keys */
85 /* _nx_secure_tls_process_remote_certificate */
86 /* Process remote certificate */
87 /* _nx_secure_tls_process_certificate_verify */
88 /* Process certificate verify */
89 /* _nx_secure_tls_send_certificate_request */
90 /* Send certificate request */
91 /* tx_mutex_get Get protection mutex */
92 /* tx_mutex_put Put protection mutex */
93 /* [nx_secure_dtls_receive_notify] Notify aaplication of packet */
94 /* receive */
95 /* */
96 /* CALLED BY */
97 /* */
98 /* _nx_secure_dtls_process_record Process DTLS record data */
99 /* */
100 /* RELEASE HISTORY */
101 /* */
102 /* DATE NAME DESCRIPTION */
103 /* */
104 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
105 /* 09-30-2020 Timothy Stapko Modified comment(s), */
106 /* verified memcpy use cases, */
107 /* verified memmove use cases, */
108 /* fixed renegotiation bug, */
109 /* fixed certificate buffer */
110 /* allocation, */
111 /* resulting in version 6.1 */
112 /* 12-31-2020 Timothy Stapko Modified comment(s), */
113 /* improved buffer length */
114 /* verification, */
115 /* resulting in version 6.1.3 */
116 /* 01-31-2022 Timothy Stapko Modified comment(s), */
117 /* fixed out-of-order handling,*/
118 /* resulting in version 6.1.10 */
119 /* 07-29-2022 Yuxin Zhou Modified comment(s), */
120 /* removed duplicated alert, */
121 /* resulting in version 6.1.12 */
122 /* */
123 /**************************************************************************/
_nx_secure_dtls_server_handshake(NX_SECURE_DTLS_SESSION * dtls_session,UCHAR * packet_buffer,UINT data_length,ULONG wait_option)124 UINT _nx_secure_dtls_server_handshake(NX_SECURE_DTLS_SESSION *dtls_session, UCHAR *packet_buffer,
125 UINT data_length, ULONG wait_option)
126 {
127 #ifndef NX_SECURE_TLS_SERVER_DISABLED
128 UINT status;
129 USHORT message_type;
130 UINT header_bytes;
131 UINT message_length;
132 UINT message_seq;
133 UINT fragment_offset;
134 UINT fragment_length;
135 NX_PACKET *send_packet;
136 NX_PACKET_POOL *packet_pool;
137 UCHAR *packet_start;
138 NX_SECURE_TLS_SESSION *tls_session;
139 UCHAR *fragment_buffer;
140
141
142 /* Basic state machine for handshake:
143 * 1. We have received a handshake message, now process the header.
144 * 2. Then process the message itself and populate the TLS socket structure.
145 * 3. Follow up with whatever actions are needed.
146 */
147
148 /* Save a pointer to the start of our packet for the hash that happens below. */
149 packet_start = packet_buffer;
150
151
152
153 /* Get a reference to TLS state. */
154 tls_session = &dtls_session -> nx_secure_dtls_tls_session;
155
156 /* Use the TLS packet buffer for fragment processing. */
157 fragment_buffer = tls_session->nx_secure_tls_packet_buffer;
158
159 header_bytes = data_length;
160
161 /* First, process the handshake message to get our state and any data therein. */
162 status = _nx_secure_dtls_process_handshake_header(packet_buffer, &message_type, &header_bytes,
163 &message_length, &message_seq, &fragment_offset, &fragment_length);
164
165 if (status == NX_SUCCESS)
166 {
167 /* For now, if we see a repeated message sequence, assume an unnecessary retransmission and ignore. */
168 /* Don't ignore sequence 0 - it's a new handshake request! */
169 if (message_seq < dtls_session -> nx_secure_dtls_remote_handshake_sequence)
170 {
171 /* Re-transmitted message. */
172 return(NX_CONTINUE);
173 }
174
175 /* When we receive a message fragment, subtract it from the current fragment length. */
176 if ((header_bytes + fragment_length) > data_length)
177 {
178 return(NX_SECURE_TLS_INCORRECT_MESSAGE_LENGTH);
179 }
180
181 /* Check the fragment_length with the lenght of packet buffer. */
182 if ((header_bytes + fragment_length) > data_length)
183 {
184 return(NX_SECURE_TLS_INCORRECT_MESSAGE_LENGTH);
185 }
186
187 /* Check available area of buffer. */
188 if ((fragment_offset + fragment_length) > tls_session -> nx_secure_tls_packet_buffer_size ||
189 (header_bytes + message_length) > tls_session -> nx_secure_tls_packet_buffer_size)
190 {
191 return(NX_SECURE_TLS_PACKET_BUFFER_TOO_SMALL);
192 }
193
194 /* If this message sequence isn't what we expect, continue reading packets. */
195 if(message_seq != dtls_session -> nx_secure_dtls_expected_handshake_sequence)
196 {
197 return(NX_SECURE_TLS_OUT_OF_ORDER_MESSAGE);
198 }
199
200 /* If we have a new sequence number, we have a new record (may be fragmented). Unless
201 the sequence number is 0, which means it is the first record. */
202 if (message_seq > dtls_session -> nx_secure_dtls_remote_handshake_sequence || (message_seq == 0 && fragment_offset == 0))
203 {
204 /* New record starting, reset the fragment length and handshake sequence number. */
205 dtls_session -> nx_secure_dtls_remote_handshake_sequence = message_seq;
206 dtls_session -> nx_secure_dtls_fragment_length = message_length;
207 }
208
209 if (fragment_length > dtls_session -> nx_secure_dtls_fragment_length)
210 {
211 return(NX_SECURE_TLS_INVALID_PACKET);
212 }
213
214 /* When we receive a message fragment, subtract it from the current fragment length. */
215 dtls_session -> nx_secure_dtls_fragment_length -= fragment_length;
216
217 /* Copy the fragment data (minus the header) into the reassembly buffer. */
218 NX_SECURE_MEMCPY(&fragment_buffer[fragment_offset], &packet_buffer[header_bytes], fragment_length); /* Use case of memcpy is verified. */
219
220 /* If we still have fragments to add, just return success. */
221 if (dtls_session -> nx_secure_dtls_fragment_length > 0)
222 {
223 return(NX_SUCCESS);
224 }
225 else
226 {
227 /* At beginning of handshake, reset the expected sequence number. */
228 if (message_seq == 0)
229 {
230 dtls_session -> nx_secure_dtls_expected_handshake_sequence = 0;
231 }
232
233 /* If the recontructed message has a sequence number not equal to the expected, it's
234 a retransmission or out-of-order message we need to ignore. */
235 if (message_seq != dtls_session -> nx_secure_dtls_expected_handshake_sequence)
236 {
237 return(NX_CONTINUE);
238 }
239
240 /* Our next expected handshake message sequence number is 1 greater than this one. */
241 dtls_session -> nx_secure_dtls_expected_handshake_sequence = message_seq + 1;
242
243 /* Put the header into the packet buffer, adjusting the fields to create a seam-less
244 * DTLS record. */
245 NX_SECURE_MEMMOVE(&fragment_buffer[header_bytes], fragment_buffer, message_length); /* Use case of memmove is verified. */
246
247 /* Reconstruct the header in the fragment buffer so we can hash the
248 reconstructed record as if it were never fragmented. */
249
250 /* Type. */
251 fragment_buffer[0] = (UCHAR)message_type;
252
253 /* Length. */
254 fragment_buffer[1] = (UCHAR)(message_length >> 16);
255 fragment_buffer[2] = (UCHAR)(message_length >> 8);
256 fragment_buffer[3] = (UCHAR)(message_length);
257
258 /* Sequence. */
259 fragment_buffer[4] = (UCHAR)(message_seq >> 8);
260 fragment_buffer[5] = (UCHAR)(message_seq);
261
262 /* Fragment offset is now 0. */
263 fragment_buffer[6] = 0;
264 fragment_buffer[7] = 0;
265 fragment_buffer[8] = 0;
266
267 /* Fragment length is now == message length. */
268 fragment_buffer[9] = (UCHAR)(message_length >> 16);
269 fragment_buffer[10] = (UCHAR)(message_length >> 8);
270 fragment_buffer[11] = (UCHAR)(message_length);
271
272 /* We have a reassembled DTLS record, use that for the handshake. */
273 packet_buffer = fragment_buffer + header_bytes;
274 packet_start = fragment_buffer;
275 }
276 }
277
278 if (status != NX_SECURE_TLS_SUCCESS)
279 {
280 return(status);
281 }
282
283 /* Get reference to the packet pool so we can allocate a packet for all send operations. */
284 packet_pool = tls_session -> nx_secure_tls_packet_pool;
285
286 /* We need to hash all of the handshake messages that we receive and send. If this message is a ClientHello,
287 then we need to initialize the hashes (TLS 1.1 uses both MD5 and SHA-1). The final hash is generated
288 in the "Finished" message. */
289 if (message_type == NX_SECURE_TLS_CLIENT_HELLO)
290 {
291 /* Initialize the handshake hashes used for the Finished message. */
292 _nx_secure_tls_handshake_hash_init(tls_session);
293 }
294
295 /* Process the message itself information from the header. */
296 switch (message_type)
297 {
298 case NX_SECURE_TLS_CLIENT_HELLO:
299 /* Client is establishing a TLS session with our server. */
300 status = _nx_secure_dtls_process_clienthello(dtls_session, packet_buffer, message_length);
301
302 /* This is the end of a flight, clear out the transmit queue. */
303 _nx_secure_dtls_retransmit_queue_flush(dtls_session);
304 break;
305 #ifdef NX_SECURE_ENABLE_CLIENT_CERTIFICATE_VERIFY
306 case NX_SECURE_TLS_CERTIFICATE_MSG:
307 /* Client sent certificate message (in response to a request from us. Process it now. */
308 status = _nx_secure_tls_process_remote_certificate(tls_session, packet_buffer, message_length, message_length);
309 tls_session -> nx_secure_tls_server_state = NX_SECURE_TLS_SERVER_STATE_CLIENT_CERTIFICATE;
310 break;
311 case NX_SECURE_TLS_CERTIFICATE_VERIFY:
312 /* Client has responded to a certificate request with a CertificateVerify message. */
313 status = _nx_secure_tls_process_certificate_verify(tls_session, packet_buffer, message_length);
314
315 if(status == NX_SUCCESS)
316 {
317 /* If remote certificate verification was a success, we have received credentials
318 from the remote host and may now pass Finished message processing once received. */
319 tls_session -> nx_secure_tls_received_remote_credentials = NX_TRUE;
320 }
321
322 tls_session -> nx_secure_tls_server_state = NX_SECURE_TLS_SERVER_STATE_CERTIFICATE_VERIFY;
323 break;
324 #endif /* NX_SECURE_ENABLE_CLIENT_CERTIFICATE_VERIFY */
325 case NX_SECURE_TLS_CLIENT_KEY_EXCHANGE:
326 /* Received a client key exchange message, meaning it is time to generate keys if we can. */
327 status = _nx_secure_tls_process_client_key_exchange(tls_session, packet_buffer, message_length, NX_SECURE_DTLS);
328 tls_session -> nx_secure_tls_server_state = NX_SECURE_TLS_SERVER_STATE_KEY_EXCHANGE;
329
330 if (status == NX_SECURE_TLS_SUCCESS)
331 {
332 /* Generate our key material from the data collected thus far and put it all into our
333 socket structure. */
334 status = _nx_secure_tls_generate_keys(tls_session);
335 }
336 break;
337 case NX_SECURE_TLS_FINISHED:
338 /* Final handshake message from the client, process it (verify the client handshake hash). */
339 status = _nx_secure_tls_process_finished(tls_session, packet_buffer, message_length);
340 tls_session -> nx_secure_tls_server_state = NX_SECURE_TLS_SERVER_STATE_FINISH_HANDSHAKE;
341
342 /* This is the end of a flight, clear out the transmit queue. */
343 _nx_secure_dtls_retransmit_queue_flush(dtls_session);
344 break;
345 case NX_SECURE_TLS_HELLO_VERIFY_REQUEST:
346 case NX_SECURE_TLS_HELLO_REQUEST:
347 case NX_SECURE_TLS_SERVER_HELLO:
348 case NX_SECURE_TLS_SERVER_KEY_EXCHANGE:
349 case NX_SECURE_TLS_CERTIFICATE_REQUEST:
350 case NX_SECURE_TLS_SERVER_HELLO_DONE:
351 case NX_SECURE_TLS_CERTIFICATE_URL:
352 case NX_SECURE_TLS_CERTIFICATE_STATUS:
353 default:
354 /* The message received was not a valid TLS server handshake message, send alert and return. */
355 status = NX_SECURE_TLS_UNEXPECTED_MESSAGE;
356 break;
357 }
358
359 /* Check for errors in processing messages. */
360 if (status != NX_SECURE_TLS_SUCCESS)
361 {
362
363 return(status);
364 }
365
366 /* Hash this handshake message. We do not hash HelloRequest messages, but since only the server will send them,
367 we do not worry about them here because these are only messages received from the client at this point.
368 Hashes include the handshake layer header but not the record layer header. */
369 _nx_secure_tls_handshake_hash_update(tls_session, packet_start, (UINT)(message_length + header_bytes));
370
371 /* Now take any actions based on state set in the message processing. */
372 switch (tls_session -> nx_secure_tls_server_state)
373 {
374 case NX_SECURE_TLS_SERVER_STATE_ALERT_SENT:
375 /* This means an error was encountered at some point in processing a valid message. At this point
376 the alert was sent, so just return a status indicating as much. */
377 return(NX_SECURE_TLS_HANDSHAKE_FAILURE);
378 break;
379 case NX_SECURE_TLS_SERVER_STATE_SEND_HELLO_VERIFY:
380 /* We have received and processed a client hello. Now respond to the client appropriately. */
381 status = _nx_secure_dtls_allocate_handshake_packet(dtls_session, packet_pool, &send_packet, wait_option);
382
383 if (status != NX_SUCCESS)
384 {
385 break;
386 }
387
388 _nx_secure_dtls_send_helloverifyrequest(dtls_session, send_packet);
389 status = _nx_secure_dtls_send_handshake_record(dtls_session, send_packet, NX_SECURE_TLS_HELLO_VERIFY_REQUEST, wait_option, 1);
390
391 if (status != NX_SUCCESS)
392 {
393 break;
394 }
395
396 if (!dtls_session -> nx_secure_dtls_tls_session.nx_secure_tls_local_session_active)
397 {
398
399 /* Ignore the protocol version in a ClientHello without cookies. */
400 dtls_session -> nx_secure_dtls_tls_session.nx_secure_tls_protocol_version = 0;
401 }
402
403 break;
404 case NX_SECURE_TLS_SERVER_STATE_SEND_HELLO:
405 /* We have received and processed a client hello. Now respond to the client appropriately. */
406 status = _nx_secure_dtls_allocate_handshake_packet(dtls_session, packet_pool, &send_packet, wait_option);
407
408 if (status != NX_SUCCESS)
409 {
410 break;
411 }
412
413 _nx_secure_dtls_send_serverhello(dtls_session, send_packet);
414 status = _nx_secure_dtls_send_handshake_record(dtls_session, send_packet, NX_SECURE_TLS_SERVER_HELLO, wait_option, 1);
415
416 if (status != NX_SUCCESS)
417 {
418 break;
419 }
420
421 /* For PSK and ECJPAKE ciphersuites, don't send the certificate message. */
422 if (tls_session -> nx_secure_tls_session_ciphersuite -> nx_secure_tls_public_auth -> nx_crypto_algorithm != NX_CRYPTO_KEY_EXCHANGE_PSK &&
423 tls_session -> nx_secure_tls_session_ciphersuite -> nx_secure_tls_public_auth -> nx_crypto_algorithm != NX_CRYPTO_KEY_EXCHANGE_ECJPAKE)
424 {
425 status = _nx_secure_dtls_allocate_handshake_packet(dtls_session, packet_pool, &send_packet, wait_option);
426
427 if (status != NX_SUCCESS)
428 {
429 break;
430 }
431
432 _nx_secure_tls_send_certificate(tls_session, send_packet, wait_option);
433 status = _nx_secure_dtls_send_handshake_record(dtls_session, send_packet, NX_SECURE_TLS_CERTIFICATE_MSG, wait_option, 1);
434 if (status != NX_SUCCESS)
435 {
436 break;
437 }
438 }
439
440 #if defined(NX_SECURE_ENABLE_PSK_CIPHERSUITES) || defined(NX_SECURE_ENABLE_ECJPAKE_CIPHERSUITE) || defined(NX_SECURE_ENABLE_ECC_CIPHERSUITE)
441 if (tls_session -> nx_secure_tls_session_ciphersuite -> nx_secure_tls_public_auth -> nx_crypto_algorithm == NX_CRYPTO_KEY_EXCHANGE_PSK ||
442 tls_session -> nx_secure_tls_session_ciphersuite -> nx_secure_tls_public_auth -> nx_crypto_algorithm == NX_CRYPTO_KEY_EXCHANGE_ECJPAKE ||
443 tls_session -> nx_secure_tls_session_ciphersuite -> nx_secure_tls_public_cipher -> nx_crypto_algorithm == NX_CRYPTO_KEY_EXCHANGE_ECDHE)
444 {
445 /* PSK or ECJPAKE ciphersuites use the ServerKeyExchange message to send cryptographic information. */
446 status = _nx_secure_dtls_allocate_handshake_packet(dtls_session, packet_pool, &send_packet, wait_option);
447
448 if (status != NX_SUCCESS)
449 {
450 break;
451 }
452
453 /* This is a PSK or ECJPAKE ciphersuite so we always send a ServerKeyExchange message. */
454 status = _nx_secure_tls_send_server_key_exchange(tls_session, send_packet);
455 if (status != NX_SUCCESS)
456 {
457 break;
458 }
459
460 status = _nx_secure_dtls_send_handshake_record(dtls_session, send_packet, NX_SECURE_TLS_SERVER_KEY_EXCHANGE, wait_option, 1);
461 if (status != NX_SUCCESS)
462 {
463 break;
464 }
465 }
466 #endif
467
468 #ifdef NX_SECURE_ENABLE_CLIENT_CERTIFICATE_VERIFY
469 /* Application has requested that we request and verify the remote Client certificate. */
470 if (tls_session -> nx_secure_tls_verify_client_certificate)
471 {
472 /* Allocate a packet for our certificate request message. */
473 status = _nx_secure_dtls_allocate_handshake_packet(dtls_session, packet_pool, &send_packet, wait_option);
474
475 if (status != NX_SUCCESS)
476 {
477 break;
478 }
479
480 /* Populate our packet with the desired message (CertificateRequest). */
481 status = _nx_secure_tls_send_certificate_request(tls_session, send_packet);
482 NX_ASSERT(status == NX_SUCCESS);
483
484 status = _nx_secure_dtls_send_handshake_record(dtls_session, send_packet, NX_SECURE_TLS_CERTIFICATE_REQUEST, wait_option, 1);
485 if (status != NX_SUCCESS)
486 {
487 break;
488 }
489 }
490 else
491 #endif
492 {
493 /* Server is not expecting credentials, so indicate that we have received the client's credentials
494 to pass Finished processing. */
495 tls_session -> nx_secure_tls_received_remote_credentials = NX_TRUE;
496 }
497
498 status = _nx_secure_dtls_allocate_handshake_packet(dtls_session, packet_pool, &send_packet, wait_option);
499
500 if (status != NX_SUCCESS)
501 {
502 break;
503 }
504
505 /* Server hello done message is 0 bytes, but it still has a TLS header so don't modify the length here. */
506 status = _nx_secure_dtls_send_handshake_record(dtls_session, send_packet, NX_SECURE_TLS_SERVER_HELLO_DONE, wait_option, 1);
507
508 if (status != NX_SUCCESS)
509 {
510 break;
511 }
512
513
514 tls_session -> nx_secure_tls_server_state = NX_SECURE_TLS_SERVER_STATE_HELLO_SENT;
515
516 break;
517 case NX_SECURE_TLS_SERVER_STATE_CLIENT_CERTIFICATE:
518 /* We processed the certificate above, do nothing. */
519 break;
520 case NX_SECURE_TLS_SERVER_STATE_CERTIFICATE_VERIFY:
521 /* We processed the certificate above, do nothing. */
522 break;
523 case NX_SECURE_TLS_SERVER_STATE_HELLO_SENT:
524 /* We sent a serverhellodone message, but we haven't received the next client message - this
525 is likely an error. */
526 break;
527 case NX_SECURE_TLS_SERVER_STATE_KEY_EXCHANGE:
528 break;
529 case NX_SECURE_TLS_SERVER_STATE_FINISH_HANDSHAKE:
530 /* Release the protection before suspending on nx_packet_allocate. */
531 tx_mutex_put(&_nx_secure_tls_protection);
532
533 /* We have received everything we need to complete the handshake and keys have been
534 * generated above. Now end the handshake with a ChangeCipherSpec (indicating following
535 * messages are encrypted) and the encrypted Finished message. */
536
537 status = _nx_secure_dtls_packet_allocate(dtls_session, packet_pool, &send_packet, wait_option);
538
539 /* Get the protection after nx_packet_allocate. */
540 tx_mutex_get(&_nx_secure_tls_protection, TX_WAIT_FOREVER);
541
542 if (status != NX_SUCCESS)
543 {
544 break;
545 }
546
547 _nx_secure_tls_send_changecipherspec(tls_session, send_packet);
548
549 /* ChangeCipherSpec is NOT a handshake message, so send as a normal TLS record. */
550 status = _nx_secure_dtls_send_record(dtls_session, send_packet, NX_SECURE_TLS_CHANGE_CIPHER_SPEC, wait_option);
551
552 if (status != NX_SUCCESS)
553 {
554 break;
555 }
556
557 /* The local session is now active since we sent the changecipherspec message.
558 NOTE: Do not set this flag until after the changecipherspec message has been passed to the send record
559 routine - this flag causes encryption and hashing to happen on records. ChangeCipherSpec should be the last
560 un-encrypted/un-hashed record sent. */
561 tls_session -> nx_secure_tls_local_session_active = 1;
562
563 /* For DTLS, reset sequence number and advance epoch right after CCS message is sent. */
564 NX_SECURE_MEMSET(tls_session -> nx_secure_tls_local_sequence_number, 0, sizeof(tls_session -> nx_secure_tls_local_sequence_number));
565
566 status = _nx_secure_tls_session_keys_set(tls_session, NX_SECURE_TLS_KEY_SET_LOCAL);
567
568 if (status != NX_SUCCESS)
569 {
570 break;
571 }
572
573 /* Advance the DTLS epoch - all messages after the ChangeCipherSpec are in a new epoch. */
574 dtls_session -> nx_secure_dtls_local_epoch = (USHORT)(dtls_session -> nx_secure_dtls_local_epoch + 1);
575
576 /* We processed the incoming finished message above, so now we can send our own finished message. */
577 status = _nx_secure_dtls_allocate_handshake_packet(dtls_session, packet_pool, &send_packet, wait_option);
578 if (status != NX_SUCCESS)
579 {
580 break;
581 }
582
583 _nx_secure_tls_send_finished(tls_session, send_packet);
584 status = _nx_secure_dtls_send_handshake_record(dtls_session, send_packet, NX_SECURE_TLS_FINISHED, wait_option, 1);
585
586
587 tls_session -> nx_secure_tls_server_state = NX_SECURE_TLS_SERVER_STATE_HANDSHAKE_FINISHED;
588
589 /* Check if application data is received before state change to NX_SECURE_TLS_SERVER_STATE_HANDSHAKE_FINISHED. */
590 if (dtls_session -> nx_secure_dtls_receive_queue_head)
591 {
592
593 /* Notify application. */
594 dtls_session -> nx_secure_dtls_server_parent -> nx_secure_dtls_receive_notify(dtls_session);
595 }
596
597 break;
598 case NX_SECURE_TLS_SERVER_STATE_HANDSHAKE_FINISHED:
599 /* Handshake is complete. */
600 break;
601 default:
602 status = NX_SECURE_TLS_INVALID_STATE;
603 }
604
605
606 return(status);
607 #else /* TLS Server disabled. */
608
609 /* We don't use the parameters since this is an error case. */
610 NX_PARAMETER_NOT_USED(packet_buffer);
611 NX_PARAMETER_NOT_USED(wait_option);
612
613 /* If TLS Server is disabled and we are in the server state machine, something is wrong... */
614 dtls_session -> nx_secure_dtls_tls_session.nx_secure_tls_client_state = NX_SECURE_TLS_CLIENT_STATE_ERROR;
615 return(NX_SECURE_TLS_INVALID_STATE);
616 #endif
617 }
618 #endif /* NX_SECURE_ENABLE_DTLS */
619
620