1 /***************************************************************************
2  * Copyright (c) 2024 Microsoft Corporation
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the MIT License which is available at
6  * https://opensource.org/licenses/MIT.
7  *
8  * SPDX-License-Identifier: MIT
9  **************************************************************************/
10 
11 
12 /**************************************************************************/
13 /**************************************************************************/
14 /**                                                                       */
15 /** NetX Secure Component                                                 */
16 /**                                                                       */
17 /**    Transport Layer Security (TLS)                                     */
18 /**                                                                       */
19 /**************************************************************************/
20 /**************************************************************************/
21 
22 #define NX_SECURE_SOURCE_CODE
23 
24 
25 #include "nx_secure_tls.h"
26 
27 /**************************************************************************/
28 /*                                                                        */
29 /*  FUNCTION                                               RELEASE        */
30 /*                                                                        */
31 /*    _nx_secure_tls_process_server_key_exchange           PORTABLE C     */
32 /*                                                           6.2.0        */
33 /*  AUTHOR                                                                */
34 /*                                                                        */
35 /*    Timothy Stapko, Microsoft Corporation                               */
36 /*                                                                        */
37 /*  DESCRIPTION                                                           */
38 /*                                                                        */
39 /*    This function processes an incoming ServerKeyExchange message,      */
40 /*    which is sent by the remote TLS Server host when certain            */
41 /*    ciphersuites (e.g. those using Diffie-Hellman) are used.            */
42 /*                                                                        */
43 /*  INPUT                                                                 */
44 /*                                                                        */
45 /*    tls_session                           TLS control block             */
46 /*    packet_buffer                         Pointer to message data       */
47 /*    message_length                        Length of message data (bytes)*/
48 /*                                                                        */
49 /*  OUTPUT                                                                */
50 /*                                                                        */
51 /*    status                                Completion status             */
52 /*                                                                        */
53 /*  CALLS                                                                 */
54 /*                                                                        */
55 /*    _nx_secure_tls_find_curve_method      Find named curve used         */
56 /*    _nx_secure_x509_remote_endpoint_certificate_get                     */
57 /*                                          Get remote host certificate   */
58 /*    _nx_secure_x509_find_certificate_methods                            */
59 /*                                          Find certificate methods      */
60 /*    _nx_secure_x509_pkcs7_decode          Decode the PKCS#7 signature   */
61 /*    [nx_crypto_init]                      Crypto initialization         */
62 /*    [nx_crypto_operation]                 Crypto operation              */
63 /*                                                                        */
64 /*  CALLED BY                                                             */
65 /*                                                                        */
66 /*    _nx_secure_dtls_client_handshake      DTLS client state machine     */
67 /*    _nx_secure_tls_client_handshake       TLS client state machine      */
68 /*                                                                        */
69 /*  RELEASE HISTORY                                                       */
70 /*                                                                        */
71 /*    DATE              NAME                      DESCRIPTION             */
72 /*                                                                        */
73 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
74 /*  09-30-2020     Timothy Stapko           Modified comment(s), update   */
75 /*                                            ECC find curve method,      */
76 /*                                            verified memcpy use cases,  */
77 /*                                            resulting in version 6.1    */
78 /*  04-25-2022     Yuxin Zhou               Modified comment(s),          */
79 /*                                            removed unnecessary code,   */
80 /*                                            resulting in version 6.1.11 */
81 /*  07-29-2022     Yuxin Zhou               Modified comment(s), improved */
82 /*                                            buffer length verification, */
83 /*                                            resulting in version 6.1.12 */
84 /*  10-31-2022     Yanwu Cai                Modified comment(s), added    */
85 /*                                            custom secret generation,   */
86 /*                                            resulting in version 6.2.0  */
87 /*                                                                        */
88 /**************************************************************************/
_nx_secure_tls_process_server_key_exchange(NX_SECURE_TLS_SESSION * tls_session,UCHAR * packet_buffer,UINT message_length)89 UINT _nx_secure_tls_process_server_key_exchange(NX_SECURE_TLS_SESSION *tls_session,
90                                                 UCHAR *packet_buffer, UINT message_length)
91 {
92 
93 #if !defined(NX_SECURE_TLS_CLIENT_DISABLED)
94 UINT                                  status;
95 #if defined(NX_SECURE_ENABLE_PSK_CIPHERSUITES) || defined(NX_SECURE_ENABLE_ECJPAKE_CIPHERSUITE) || \
96    (defined(NX_SECURE_ENABLE_ECC_CIPHERSUITE))
97 const NX_SECURE_TLS_CIPHERSUITE_INFO *ciphersuite;
98 #endif /* defined(NX_SECURE_ENABLE_PSK_CIPHERSUITES) || defined(NX_SECURE_ENABLE_ECJPAKE_CIPHERSUITE) */
99 
100 #if defined(NX_SECURE_ENABLE_PSK_CIPHERSUITES) || defined(NX_SECURE_ENABLE_ECJPAKE_CIPHERSUITE) || \
101    (defined(NX_SECURE_ENABLE_ECC_CIPHERSUITE))
102     /* Figure out which ciphersuite we are using. */
103     ciphersuite = tls_session -> nx_secure_tls_session_ciphersuite;
104     if (ciphersuite == NX_NULL)
105     {
106 
107         /* Likely internal error since at this point ciphersuite negotiation was theoretically completed. */
108         return(NX_SECURE_TLS_UNKNOWN_CIPHERSUITE);
109     }
110 #endif /* defined(NX_SECURE_ENABLE_PSK_CIPHERSUITES) || defined(NX_SECURE_ENABLE_ECJPAKE_CIPHERSUITE) */
111 
112 
113 #if defined(NX_SECURE_ENABLE_ECC_CIPHERSUITE)
114 
115     if (ciphersuite -> nx_secure_tls_public_cipher -> nx_crypto_algorithm == NX_CRYPTO_KEY_EXCHANGE_ECDHE)
116     {
117         if (tls_session -> nx_secure_tls_client_state != NX_SECURE_TLS_CLIENT_STATE_SERVER_CERTIFICATE)
118         {
119             return(NX_SECURE_TLS_UNEXPECTED_MESSAGE);
120         }
121 
122         tls_session -> nx_secure_tls_client_state = NX_SECURE_TLS_CLIENT_STATE_SERVER_KEY_EXCHANGE;
123 
124     }
125 
126     status = tls_session -> nx_secure_process_server_key_exchange(tls_session -> nx_secure_tls_session_ciphersuite, tls_session -> nx_secure_tls_crypto_table,
127                                                                   tls_session -> nx_secure_tls_protocol_version, packet_buffer, message_length,
128                                                                   &tls_session -> nx_secure_tls_key_material, &tls_session -> nx_secure_tls_credentials,
129                                                                   &tls_session -> nx_secure_tls_handshake_hash, tls_session -> nx_secure_public_cipher_metadata_area,
130                                                                   tls_session -> nx_secure_public_cipher_metadata_size,
131                                                                   tls_session -> nx_secure_public_auth_metadata_area, tls_session -> nx_secure_public_auth_metadata_size,
132                                                                   &tls_session -> nx_secure_tls_ecc);
133 
134 #else
135     status = tls_session -> nx_secure_process_server_key_exchange(tls_session -> nx_secure_tls_session_ciphersuite, tls_session -> nx_secure_tls_crypto_table,
136                                                                   tls_session -> nx_secure_tls_protocol_version, packet_buffer, message_length,
137                                                                   &tls_session -> nx_secure_tls_key_material, &tls_session -> nx_secure_tls_credentials,
138                                                                   &tls_session -> nx_secure_tls_handshake_hash, tls_session -> nx_secure_public_cipher_metadata_area,
139                                                                   tls_session -> nx_secure_public_cipher_metadata_size,
140                                                                   tls_session -> nx_secure_public_auth_metadata_area, tls_session -> nx_secure_public_auth_metadata_size,
141                                                                   NX_NULL);
142 
143 #endif /* defined(NX_SECURE_ENABLE_ECC_CIPHERSUITE) */
144 
145     return(status);
146 
147 #else /* !define(NX_SECURE_TLS_CLIENT_DISABLED) */
148 
149     /* If Client TLS is disabled and we recieve a server key exchange, error! */
150     NX_PARAMETER_NOT_USED(tls_session);
151     NX_PARAMETER_NOT_USED(packet_buffer);
152     NX_PARAMETER_NOT_USED(message_length);
153 
154     return(NX_SECURE_TLS_UNEXPECTED_MESSAGE);
155 #endif
156 }
157 
158