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 #include "nx_secure_tls.h"
25 
26 /**************************************************************************/
27 /*                                                                        */
28 /*  FUNCTION                                               RELEASE        */
29 /*                                                                        */
30 /*    _nx_secure_tls_psk_find                             PORTABLE C      */
31 /*                                                           6.2.0        */
32 /*  AUTHOR                                                                */
33 /*                                                                        */
34 /*    Timothy Stapko, Microsoft Corporation                               */
35 /*                                                                        */
36 /*  DESCRIPTION                                                           */
37 /*                                                                        */
38 /*    This function finds a pre-shared key (PSK) in a TLS session for use */
39 /*    with a PSK ciphersuite. The PSK is found using an "identity hint"   */
40 /*    that should match a field in the PSK structure in the TLS session.  */
41 /*                                                                        */
42 /*  INPUT                                                                 */
43 /*                                                                        */
44 /*    tls_credentials                       TLS credentials               */
45 /*    psk_data                              Pointer to PSK data           */
46 /*    psk_length                            Length of PSK data            */
47 /*    psk_identity_hint                     PSK identity hint data        */
48 /*    identity_length                       Length of identity data       */
49 /*    psk_store_index                       Index of found PSK in store   */
50 /*                                                                        */
51 /*  OUTPUT                                                                */
52 /*                                                                        */
53 /*    status                                Completion status             */
54 /*                                                                        */
55 /*  CALLS                                                                 */
56 /*                                                                        */
57 /*    tx_mutex_get                          Get protection mutex          */
58 /*    tx_mutex_put                          Put protection mutex          */
59 /*                                                                        */
60 /*  CALLED BY                                                             */
61 /*                                                                        */
62 /*    _nx_secure_generate_premaster_secret  Generate the shared secret    */
63 /*                                            used to generate keys later */
64 /*                                                                        */
65 /*  RELEASE HISTORY                                                       */
66 /*                                                                        */
67 /*    DATE              NAME                      DESCRIPTION             */
68 /*                                                                        */
69 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
70 /*  09-30-2020     Timothy Stapko           Modified comment(s),          */
71 /*                                            resulting in version 6.1    */
72 /*  10-31-2022     Yanwu Cai                Modified comment(s),          */
73 /*                                            updated parameters list,    */
74 /*                                            resulting in version 6.2.0  */
75 /*                                                                        */
76 /**************************************************************************/
77 #if defined(NX_SECURE_ENABLE_PSK_CIPHERSUITES) || defined(NX_SECURE_ENABLE_ECJPAKE_CIPHERSUITE)
_nx_secure_tls_psk_find(NX_SECURE_TLS_CREDENTIALS * tls_credentials,UCHAR ** psk_data,UINT * psk_length,UCHAR * psk_identity_hint,UINT identity_length,UINT * psk_store_index)78 UINT _nx_secure_tls_psk_find(NX_SECURE_TLS_CREDENTIALS *tls_credentials, UCHAR **psk_data, UINT *psk_length,
79                              UCHAR *psk_identity_hint, UINT identity_length, UINT *psk_store_index)
80 {
81 UINT psk_list_size;
82 UINT compare_val;
83 UINT i;
84 
85     /* Get the protection. */
86     tx_mutex_get(&_nx_secure_tls_protection, TX_WAIT_FOREVER);
87 
88     psk_list_size = tls_credentials -> nx_secure_tls_psk_count;
89 
90     if ((psk_identity_hint[0] == 0) && (psk_list_size > 0))
91     {
92 
93         /* No hint from server. Return the first associated PSK. */
94         *psk_data = tls_credentials -> nx_secure_tls_psk_store[0].nx_secure_tls_psk_data;
95         *psk_length = tls_credentials -> nx_secure_tls_psk_store[0].nx_secure_tls_psk_data_size;
96 
97         if(psk_store_index != NX_NULL)
98         {
99             *psk_store_index = 0;
100         }
101 
102         /* Release the protection. */
103         tx_mutex_put(&_nx_secure_tls_protection);
104 
105         return(NX_SUCCESS);
106     }
107 
108     /* Loop through all PSKs, looking for a matching identity string. */
109     for (i = 0; i < psk_list_size; ++i)
110     {
111         /* Save off the PSK and its length. */
112         compare_val = (UINT)NX_SECURE_MEMCMP(tls_credentials -> nx_secure_tls_psk_store[i].nx_secure_tls_psk_id_hint, psk_identity_hint, identity_length);
113 
114         /* See if the identity matched, and the length is the same (without the length, we could have a
115            matching prefix which could be a possible attack vector... */
116         if (compare_val == 0 && identity_length == tls_credentials -> nx_secure_tls_psk_store[i].nx_secure_tls_psk_id_hint_size)
117         {
118             /* Found a matching identity, return the associated PSK. */
119             *psk_data = tls_credentials -> nx_secure_tls_psk_store[i].nx_secure_tls_psk_data;
120             *psk_length = tls_credentials -> nx_secure_tls_psk_store[i].nx_secure_tls_psk_data_size;
121 
122             if(psk_store_index != NX_NULL)
123             {
124                 *psk_store_index = i;
125             }
126 
127             /* Release the protection. */
128             tx_mutex_put(&_nx_secure_tls_protection);
129 
130             return(NX_SUCCESS);
131         }
132     }
133 
134     /* Release the protection. */
135     tx_mutex_put(&_nx_secure_tls_protection);
136 
137     return(NX_SECURE_TLS_NO_MATCHING_PSK);
138 }
139 #endif
140 
141