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 /**    Transport Layer Security (TLS)                                     */
19 /**                                                                       */
20 /**************************************************************************/
21 /**************************************************************************/
22 
23 #define NX_SECURE_SOURCE_CODE
24 
25 #include "nx_secure_tls.h"
26 
27 /**************************************************************************/
28 /*                                                                        */
29 /*  FUNCTION                                               RELEASE        */
30 /*                                                                        */
31 /*    _nx_secure_tls_send_finished                        PORTABLE C      */
32 /*                                                           6.2.1        */
33 /*  AUTHOR                                                                */
34 /*                                                                        */
35 /*    Timothy Stapko, Microsoft Corporation                               */
36 /*                                                                        */
37 /*  DESCRIPTION                                                           */
38 /*                                                                        */
39 /*    This function generates the Finished message to send to the remote  */
40 /*    host. The Finished message contains a hash of all handshake         */
41 /*    messages received up to this point which is used to verify that     */
42 /*    none of the messages have been corrupted.                           */
43 /*                                                                        */
44 /*  INPUT                                                                 */
45 /*                                                                        */
46 /*    tls_session                           TLS control block             */
47 /*    send_packet                           Packet used to send message   */
48 /*                                                                        */
49 /*  OUTPUT                                                                */
50 /*                                                                        */
51 /*    status                                Completion status             */
52 /*                                                                        */
53 /*  CALLS                                                                 */
54 /*                                                                        */
55 /*    _nx_secure_tls_finished_hash_generate Generate Finished hash        */
56 /*                                                                        */
57 /*  CALLED BY                                                             */
58 /*                                                                        */
59 /*    _nx_secure_dtls_client_handshake      DTLS client state machine     */
60 /*    _nx_secure_dtls_server_handshake      DTLS server state machine     */
61 /*    _nx_secure_tls_client_handshake       TLS client state machine      */
62 /*    _nx_secure_tls_server_handshake       TLS server state machine      */
63 /*                                                                        */
64 /*  RELEASE HISTORY                                                       */
65 /*                                                                        */
66 /*    DATE              NAME                      DESCRIPTION             */
67 /*                                                                        */
68 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
69 /*  09-30-2020     Timothy Stapko           Modified comment(s),          */
70 /*                                            verified memcpy use cases,  */
71 /*                                            fixed renegotiation bug,    */
72 /*                                            resulting in version 6.1    */
73 /*  03-08-2023     Yanwu Cai                Modified comment(s),          */
74 /*                                            fixed compiler errors when  */
75 /*                                            x509 is disabled,           */
76 /*                                            resulting in version 6.2.1  */
77 /*                                                                        */
78 /**************************************************************************/
_nx_secure_tls_send_finished(NX_SECURE_TLS_SESSION * tls_session,NX_PACKET * send_packet)79 UINT _nx_secure_tls_send_finished(NX_SECURE_TLS_SESSION *tls_session, NX_PACKET *send_packet)
80 {
81 UCHAR            *finished_label;
82 UINT             hash_size = 0;
83 UINT             status;
84 UINT             is_server;
85 
86 
87     is_server = (tls_session -> nx_secure_tls_socket_type == NX_SECURE_TLS_SESSION_TYPE_SERVER);
88 
89 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
90     if(tls_session->nx_secure_tls_1_3)
91     {
92 
93         /* Generate the TLS 1.3-specific finished data. */
94         status = _nx_secure_tls_1_3_finished_hash_generate(tls_session, is_server, &hash_size,
95                                                            send_packet -> nx_packet_append_ptr,
96                                                            ((ULONG)(send_packet -> nx_packet_data_end) -
97                                                             (ULONG)(send_packet -> nx_packet_append_ptr)));
98     }
99     else
100 #endif /* (NX_SECURE_TLS_TLS_1_3_ENABLED) */
101     {
102         /* Select our label for generating the finished hash expansion. */
103         if (is_server)
104         {
105             finished_label = (UCHAR *)"server finished";
106         }
107         else
108         {
109             finished_label = (UCHAR *)"client finished";
110         }
111 
112         if (NX_SECURE_TLS_FINISHED_HASH_SIZE > ((ULONG)(send_packet -> nx_packet_data_end) - (ULONG)(send_packet -> nx_packet_append_ptr)))
113         {
114 
115             /* Packet buffer too small. */
116             return(NX_SECURE_TLS_PACKET_BUFFER_TOO_SMALL);
117         }
118 
119         /* Finally, generate the verification data required by TLS - 12 bytes using the PRF and the data
120            we have collected. Place the result directly into the packet buffer. */
121         status = _nx_secure_tls_finished_hash_generate(tls_session, finished_label, send_packet -> nx_packet_append_ptr);
122 
123 #ifndef NX_SECURE_TLS_DISABLE_SECURE_RENEGOTIATION
124         /* If we are doing secure renegotiation as per RFC 5746, we need to save off the generated
125            verify data now. For TLS 1.0-1.2 this is 12 bytes. If SSLv3 is ever used, it will be 36 bytes. */
126         NX_SECURE_MEMCPY(tls_session -> nx_secure_tls_local_verify_data, send_packet -> nx_packet_append_ptr, NX_SECURE_TLS_FINISHED_HASH_SIZE); /* Use case of memcpy is verified. lgtm[cpp/banned-api-usage-required-any] */
127 #endif
128 
129         /* The finished verify data is always 12 bytes for TLS 1.2 and earlier. */
130         hash_size = NX_SECURE_TLS_FINISHED_HASH_SIZE;
131     }
132 
133     /* Adjust the packet into which we just wrote the finished hash. */
134     send_packet -> nx_packet_append_ptr = send_packet -> nx_packet_append_ptr + hash_size;
135     send_packet -> nx_packet_length = send_packet -> nx_packet_length + hash_size;
136 
137     if (status != NX_SUCCESS)
138     {
139         return(status);
140     }
141 
142 #ifndef NX_SECURE_DISABLE_X509
143 
144     /* Finished with the handshake - we can free certificates now. */
145     status = _nx_secure_tls_remote_certificate_free_all(tls_session);
146 #endif
147 
148     return(status);
149 }
150 
151