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) - Generate Session Keys             */
19 /**                                                                       */
20 /**************************************************************************/
21 /**************************************************************************/
22 
23 #define NX_SECURE_SOURCE_CODE
24 
25 #include "nx_secure_tls.h"
26 #ifdef NX_SECURE_ENABLE_DTLS
27 #include "nx_secure_dtls.h"
28 #endif /* NX_SECURE_ENABLE_DTLS */
29 
30 
31 /**************************************************************************/
32 /*                                                                        */
33 /*  FUNCTION                                               RELEASE        */
34 /*                                                                        */
35 /*    _nx_secure_tls_generate_keys                        PORTABLE C      */
36 /*                                                           6.2.0        */
37 /*  AUTHOR                                                                */
38 /*                                                                        */
39 /*    Timothy Stapko, Microsoft Corporation                               */
40 /*                                                                        */
41 /*  DESCRIPTION                                                           */
42 /*                                                                        */
43 /*    This function generates the session keys used by TLS to encrypt     */
44 /*    the data being transmitted. It uses data gathered during the TLS    */
45 /*    handshake to generate a block of "key material" that is split into  */
46 /*    the various keys needed for each session.                           */
47 /*                                                                        */
48 /*  INPUT                                                                 */
49 /*                                                                        */
50 /*    tls_session                           TLS control block             */
51 /*                                                                        */
52 /*  OUTPUT                                                                */
53 /*                                                                        */
54 /*    status                                Completion status             */
55 /*                                                                        */
56 /*  CALLS                                                                 */
57 /*                                                                        */
58 /*    [nx_secure_generate_master_secret]    Generate master secrets       */
59 /*    [nx_secure_generate_session_keys]     Generate session keys         */
60 /*                                                                        */
61 /*  CALLED BY                                                             */
62 /*                                                                        */
63 /*    _nx_secure_dtls_client_handshake      DTLS client state machine     */
64 /*    _nx_secure_dtls_server_handshake      DTLS server state machine     */
65 /*    _nx_secure_tls_client_handshake       TLS client state machine      */
66 /*    _nx_secure_tls_server_handshake       TLS server state machine      */
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 /*                                            verified memcpy use cases,  */
75 /*                                            resulting in version 6.1    */
76 /*  10-31-2022     Yanwu Cai                Modified comment(s), added    */
77 /*                                            custom secret generation,   */
78 /*                                            resulting in version 6.2.0  */
79 /*                                                                        */
80 /**************************************************************************/
_nx_secure_tls_generate_keys(NX_SECURE_TLS_SESSION * tls_session)81 UINT _nx_secure_tls_generate_keys(NX_SECURE_TLS_SESSION *tls_session)
82 {
83 UCHAR                                *pre_master_sec;
84 UINT                                  pre_master_sec_size;
85 UCHAR                                *master_sec;
86 UINT                                  status;
87 const NX_CRYPTO_METHOD               *session_prf_method = NX_NULL;
88 const NX_SECURE_TLS_CIPHERSUITE_INFO *ciphersuite;
89 
90     /* Generate the session keys using the parameters obtained in the handshake.
91        By this point all the information needed to generate the TLS session key
92        material should have been gathered and stored in the TLS socket structure. */
93 
94     /* Generate the Master Secret from the Pre-Master Secret.
95        From the RFC (TLS 1.1, TLS 1.2):
96 
97         master_secret = PRF(pre_master_secret, "master secret",
98                         ClientHello.random + ServerHello.random) [0..47];
99 
100         The master secret is always exactly 48 bytes in length.  The length
101         of the premaster secret will vary depending on key exchange method.
102      */
103 
104     /* Figure out which ciphersuite we are using. */
105     ciphersuite = tls_session -> nx_secure_tls_session_ciphersuite;
106     if (ciphersuite == NX_NULL)
107     {
108 
109         /* Likely internal error since at this point ciphersuite negotiation was theoretically completed. */
110         return(NX_SECURE_TLS_UNKNOWN_CIPHERSUITE);
111     }
112 
113     pre_master_sec = tls_session -> nx_secure_tls_key_material.nx_secure_tls_pre_master_secret;
114     pre_master_sec_size = tls_session -> nx_secure_tls_key_material.nx_secure_tls_pre_master_secret_size;
115     master_sec = tls_session -> nx_secure_tls_key_material.nx_secure_tls_master_secret;
116 
117 
118 #if (NX_SECURE_TLS_TLS_1_2_ENABLED)
119 #ifdef NX_SECURE_ENABLE_DTLS
120     if (tls_session -> nx_secure_tls_protocol_version == NX_SECURE_TLS_VERSION_TLS_1_2 ||
121         tls_session -> nx_secure_tls_protocol_version == NX_SECURE_DTLS_VERSION_1_2)
122 #else
123     if (tls_session -> nx_secure_tls_protocol_version == NX_SECURE_TLS_VERSION_TLS_1_2)
124 #endif /* NX_SECURE_ENABLE_DTLS */
125     {
126         /* For TLS 1.2, the PRF is defined by the ciphersuite. However, if we are using an older ciphersuite,
127             * default to the TLS 1.2 default PRF, which uses SHA-256-HMAC. */
128         session_prf_method = ciphersuite -> nx_secure_tls_prf;
129     }
130 
131 #endif
132 #if (NX_SECURE_TLS_TLS_1_0_ENABLED || NX_SECURE_TLS_TLS_1_1_ENABLED)
133 #ifdef NX_SECURE_ENABLE_DTLS
134     if (tls_session -> nx_secure_tls_protocol_version == NX_SECURE_TLS_VERSION_TLS_1_0 ||
135         tls_session -> nx_secure_tls_protocol_version == NX_SECURE_TLS_VERSION_TLS_1_1 ||
136         tls_session -> nx_secure_tls_protocol_version == NX_SECURE_DTLS_VERSION_1_0)
137 #else
138     if (tls_session -> nx_secure_tls_protocol_version == NX_SECURE_TLS_VERSION_TLS_1_0 ||
139         tls_session -> nx_secure_tls_protocol_version == NX_SECURE_TLS_VERSION_TLS_1_1)
140 #endif /* NX_SECURE_ENABLE_DTLS */
141     {
142         /* TLS 1.0 and TLS 1.1 use the same PRF. */
143         session_prf_method = tls_session -> nx_secure_tls_crypto_table -> nx_secure_tls_prf_1_method;
144     }
145 #endif
146 
147     status = tls_session -> nx_secure_generate_master_secret(ciphersuite, tls_session -> nx_secure_tls_protocol_version, session_prf_method,
148                                                              &tls_session -> nx_secure_tls_key_material, pre_master_sec, pre_master_sec_size,
149                                                              master_sec, tls_session -> nx_secure_tls_prf_metadata_area,
150                                                              tls_session -> nx_secure_tls_prf_metadata_size);
151 
152     if (status != NX_SECURE_TLS_SUCCESS)
153     {
154 
155         return(status);
156     }
157 
158     /* Clear out the Pre-Master Secret (we don't need it anymore and keeping it in memory is dangerous). */
159 #ifdef NX_SECURE_KEY_CLEAR
160     NX_SECURE_MEMSET(pre_master_sec, 0x0, sizeof(tls_session -> nx_secure_tls_key_material.nx_secure_tls_pre_master_secret));
161 #endif /* NX_SECURE_KEY_CLEAR  */
162 
163 
164     status = tls_session -> nx_secure_generate_session_keys(ciphersuite, tls_session -> nx_secure_tls_protocol_version, session_prf_method,
165                                                             &tls_session -> nx_secure_tls_key_material, master_sec, tls_session -> nx_secure_tls_prf_metadata_area,
166                                                             tls_session -> nx_secure_tls_prf_metadata_size);
167     return(status);
168 }
169 
170