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 /* This local static buffer needs to be large enough to hold both the server random and the client random. */
31 static UCHAR _nx_secure_tls_gen_keys_random[NX_SECURE_TLS_RANDOM_SIZE << 1];
32 
33 /**************************************************************************/
34 /*                                                                        */
35 /*  FUNCTION                                               RELEASE        */
36 /*                                                                        */
37 /*    _nx_secure_generate_master_secret                   PORTABLE C      */
38 /*                                                           6.2.0        */
39 /*  AUTHOR                                                                */
40 /*                                                                        */
41 /*    Yanwu Cai, Microsoft Corporation                                    */
42 /*                                                                        */
43 /*  DESCRIPTION                                                           */
44 /*                                                                        */
45 /*    This function generates the session keys used by TLS to encrypt     */
46 /*    the data being transmitted. It uses data gathered during the TLS    */
47 /*    handshake to generate a block of "key material" that is split into  */
48 /*    the various keys needed for each session.                           */
49 /*                                                                        */
50 /*  INPUT                                                                 */
51 /*                                                                        */
52 /*    ciphersuite                           Selected cipher suite         */
53 /*    protocol_version                      Selected TLS version          */
54 /*    session_prf_method                    Pointer to PRF crypto method  */
55 /*    tls_key_material                      TLS key material              */
56 /*    pre_master_sec                        Pointer to pre-master secret  */
57 /*    pre_master_sec_size                   Size of pre-master secret     */
58 /*    master_sec                            Pointer to master secret      */
59 /*    prf_metadata                          Metadata for PRF crypto method*/
60 /*    prf_metadata_size                     Size of PRF metadata          */
61 /*                                                                        */
62 /*  OUTPUT                                                                */
63 /*                                                                        */
64 /*    status                                Completion status             */
65 /*                                                                        */
66 /*  CALLS                                                                 */
67 /*                                                                        */
68 /*    [nx_crypto_init]                      Initialize crypto             */
69 /*    [nx_crypto_operation]                 Crypto operation              */
70 /*                                                                        */
71 /*  CALLED BY                                                             */
72 /*                                                                        */
73 /*    _nx_secure_tls_generate_keys          Generate session keys         */
74 /*                                                                        */
75 /*  RELEASE HISTORY                                                       */
76 /*                                                                        */
77 /*    DATE              NAME                      DESCRIPTION             */
78 /*                                                                        */
79 /*  10-31-2022     Yanwu Cai                Initial Version 6.2.0         */
80 /*                                                                        */
81 /**************************************************************************/
_nx_secure_generate_master_secret(const NX_SECURE_TLS_CIPHERSUITE_INFO * ciphersuite,USHORT protocol_version,const NX_CRYPTO_METHOD * session_prf_method,NX_SECURE_TLS_KEY_MATERIAL * tls_key_material,UCHAR * pre_master_sec,UINT pre_master_sec_size,UCHAR * master_sec,VOID * prf_metadata,ULONG prf_metadata_size)82 UINT _nx_secure_generate_master_secret(const NX_SECURE_TLS_CIPHERSUITE_INFO *ciphersuite, USHORT protocol_version,
83                                        const NX_CRYPTO_METHOD *session_prf_method, NX_SECURE_TLS_KEY_MATERIAL *tls_key_material,
84                                        UCHAR *pre_master_sec, UINT pre_master_sec_size, UCHAR *master_sec,
85                                        VOID *prf_metadata, ULONG prf_metadata_size)
86 {
87 ;
88 UINT  status;
89 VOID *handler = NX_NULL;
90 
91     NX_PARAMETER_NOT_USED(protocol_version);
92 
93     /* Generate the session keys using the parameters obtained in the handshake.
94        By this point all the information needed to generate the TLS session key
95        material should have been gathered and stored in the TLS socket structure. */
96 
97     /* Generate the Master Secret from the Pre-Master Secret.
98        From the RFC (TLS 1.1, TLS 1.2):
99 
100         master_secret = PRF(pre_master_secret, "master secret",
101                         ClientHello.random + ServerHello.random) [0..47];
102 
103         The master secret is always exactly 48 bytes in length.  The length
104         of the premaster secret will vary depending on key exchange method.
105      */
106 
107     /* The generation of key material is different between RSA and DH. */
108     if (ciphersuite -> nx_secure_tls_public_cipher -> nx_crypto_algorithm == NX_CRYPTO_KEY_EXCHANGE_RSA
109 #ifdef NX_SECURE_ENABLE_ECC_CIPHERSUITE
110         || ciphersuite -> nx_secure_tls_public_cipher -> nx_crypto_algorithm == NX_CRYPTO_KEY_EXCHANGE_ECDHE
111         || ciphersuite -> nx_secure_tls_public_cipher -> nx_crypto_algorithm == NX_CRYPTO_KEY_EXCHANGE_ECDH
112 #endif /* NX_SECURE_ENABLE_ECC_CIPHERSUITE */
113 #ifdef NX_SECURE_ENABLE_PSK_CIPHERSUITES
114         || ciphersuite -> nx_secure_tls_public_auth -> nx_crypto_algorithm == NX_CRYPTO_KEY_EXCHANGE_PSK
115 #endif
116 #ifdef NX_SECURE_ENABLE_ECJPAKE_CIPHERSUITE
117         || ciphersuite -> nx_secure_tls_public_auth -> nx_crypto_algorithm == NX_CRYPTO_KEY_EXCHANGE_ECJPAKE
118 #endif
119         )
120     {
121         /* Concatenate random values to feed into PRF. */
122         NX_SECURE_MEMCPY(_nx_secure_tls_gen_keys_random, tls_key_material -> nx_secure_tls_client_random,
123                          NX_SECURE_TLS_RANDOM_SIZE); /* Use case of memcpy is verified. */
124         NX_SECURE_MEMCPY(&_nx_secure_tls_gen_keys_random[NX_SECURE_TLS_RANDOM_SIZE],
125                          tls_key_material -> nx_secure_tls_server_random, NX_SECURE_TLS_RANDOM_SIZE); /* Use case of memcpy is verified. */
126 
127         /* Generate the master secret using the pre-master secret, the defined TLS label, and the concatenated
128            random values. */
129 
130         /* If we don't have a PRF method, the version is wrong! */
131         if (session_prf_method == NX_NULL)
132         {
133 #ifdef NX_SECURE_KEY_CLEAR
134             NX_SECURE_MEMSET(_nx_secure_tls_gen_keys_random, 0, sizeof(_nx_secure_tls_gen_keys_random));
135 #endif /* NX_SECURE_KEY_CLEAR  */
136 
137             return(NX_SECURE_TLS_PROTOCOL_VERSION_CHANGED);
138         }
139 
140         /* Use the PRF to generate the master secret. */
141         if (session_prf_method -> nx_crypto_init != NX_NULL)
142         {
143             status = session_prf_method -> nx_crypto_init((NX_CRYPTO_METHOD*)session_prf_method,
144                                                  pre_master_sec, (NX_CRYPTO_KEY_SIZE)pre_master_sec_size,
145                                                  &handler,
146                                                  prf_metadata,
147                                                  prf_metadata_size);
148 
149             if(status != NX_CRYPTO_SUCCESS)
150             {
151 #ifdef NX_SECURE_KEY_CLEAR
152                 NX_SECURE_MEMSET(_nx_secure_tls_gen_keys_random, 0, sizeof(_nx_secure_tls_gen_keys_random));
153 #endif /* NX_SECURE_KEY_CLEAR  */
154 
155                 return(status);
156             }
157         }
158 
159         if (session_prf_method -> nx_crypto_operation != NX_NULL)
160         {
161             status = session_prf_method -> nx_crypto_operation(NX_CRYPTO_PRF,
162                                                       handler,
163                                                       (NX_CRYPTO_METHOD*)session_prf_method,
164                                                       (UCHAR *)"master secret",
165                                                       13,
166                                                       _nx_secure_tls_gen_keys_random,
167                                                       64,
168                                                       NX_NULL,
169                                                       master_sec,
170                                                       48,
171                                                       prf_metadata,
172                                                       prf_metadata_size,
173                                                       NX_NULL,
174                                                       NX_NULL);
175 
176 #ifdef NX_SECURE_KEY_CLEAR
177             NX_SECURE_MEMSET(_nx_secure_tls_gen_keys_random, 0, sizeof(_nx_secure_tls_gen_keys_random));
178 #endif /* NX_SECURE_KEY_CLEAR  */
179 
180             if(status != NX_CRYPTO_SUCCESS)
181             {
182                 /* Secrets cleared above. */
183                 return(status);
184             }
185         }
186 
187         if (session_prf_method -> nx_crypto_cleanup)
188         {
189             status = session_prf_method -> nx_crypto_cleanup(prf_metadata);
190 
191             if(status != NX_CRYPTO_SUCCESS)
192             {
193                 /* All secrets cleared above. */
194                 return(status);
195             }
196         }
197     }
198     else
199     {
200         /* The chosen cipher is not supported. Likely an internal error since negotiation has already finished. */
201         return(NX_SECURE_TLS_UNSUPPORTED_CIPHER);
202     }
203 
204     return(NX_SECURE_TLS_SUCCESS);
205 }
206 
207