1 /*******************************************************************************
2  * @file  sl_net_credentials.c
3  *******************************************************************************
4  * # License
5  * <b>Copyright 2024 Silicon Laboratories Inc. www.silabs.com</b>
6  *******************************************************************************
7  *
8  * SPDX-License-Identifier: Zlib
9  *
10  * The licensor of this software is Silicon Laboratories Inc.
11  *
12  * This software is provided 'as-is', without any express or implied
13  * warranty. In no event will the authors be held liable for any damages
14  * arising from the use of this software.
15  *
16  * Permission is granted to anyone to use this software for any purpose,
17  * including commercial applications, and to alter it and redistribute it
18  * freely, subject to the following restrictions:
19  *
20  * 1. The origin of this software must not be misrepresented; you must not
21  *    claim that you wrote the original software. If you use this software
22  *    in a product, an acknowledgment in the product documentation would be
23  *    appreciated but is not required.
24  * 2. Altered source versions must be plainly marked as such, and must not be
25  *    misrepresented as being the original software.
26  * 3. This notice may not be removed or altered from any source distribution.
27  *
28  ******************************************************************************/
29 
30 #include "sl_net.h"
31 #include "sl_net_default_values.h"
32 #include "sl_wifi_credentials.h"
33 #include "sl_common.h"
34 #if defined(SLI_SI917) || defined(SLI_SI915)
35 #include "sl_net_si91x.h"
36 #endif
37 #include <string.h>
38 
39 #define CRED_TYPE_CERT 0
40 #define CRED_TYPE_CRED 1
41 
42 // [SL_NET_DEFAULT_WIFI_CLIENT_CREDENTIAL_ID]
43 // [SL_NET_DEFAULT_WIFI_AP_CREDENTIAL_ID]
44 
45 sl_status_t sl_si91x_delete_credential(sl_net_credential_id_t id, sl_net_credential_type_t type);
46 
sli_si91x_check_cred_type(sl_net_credential_type_t type)47 static int sli_si91x_check_cred_type(sl_net_credential_type_t type)
48 {
49   if ((SL_NET_CERTIFICATE == type) || (SL_NET_PUBLIC_KEY == type) || (SL_NET_PRIVATE_KEY == type)
50       || (SL_NET_SIGNING_CERTIFICATE == type) || (SL_NET_PACK_FILE == type)) {
51     return CRED_TYPE_CERT;
52   }
53 
54   return CRED_TYPE_CRED;
55 }
56 
sli_si91x_get_wifi_credential_type(sl_net_credential_type_t type,sl_wifi_credential_type_t * wifi_type)57 static sl_status_t sli_si91x_get_wifi_credential_type(sl_net_credential_type_t type,
58                                                       sl_wifi_credential_type_t *wifi_type)
59 {
60   // Map the network credential type to WiFi credential type
61   switch (type) {
62     case SL_NET_WIFI_PSK:
63       // Set the credential type to Pre-Shared Key (PSK)
64       *wifi_type = SL_WIFI_PSK_CREDENTIAL;
65       break;
66     case SL_NET_WIFI_PMK:
67       // Set the credential type to Pairwise Master Key (PMK)
68       *wifi_type = SL_WIFI_PMK_CREDENTIAL;
69       break;
70     case SL_NET_WIFI_WEP:
71       // Set the credential type to Wired Equivalent Privacy (WEP)
72       *wifi_type = SL_WIFI_WEP_CREDENTIAL;
73       break;
74     case SL_NET_EAP_CLIENT_CREDENTIAL:
75       // Set the credential type to Extensible Authentication Protocol (EAP)
76       *wifi_type = SL_WIFI_EAP_CREDENTIAL;
77       break;
78     default:
79       return SL_STATUS_INVALID_PARAMETER;
80   }
81 
82   return SL_STATUS_OK;
83 }
84 
sli_si91x_get_net_credential_type(sl_wifi_credential_type_t type,sl_net_credential_type_t * net_type)85 static sl_status_t sli_si91x_get_net_credential_type(sl_wifi_credential_type_t type, sl_net_credential_type_t *net_type)
86 {
87   // Map the WiFi credential type to network credential type
88   switch (type) {
89     case SL_WIFI_PSK_CREDENTIAL:
90       // Set the credential type to Pre-Shared Key (PSK)
91       *net_type = SL_NET_WIFI_PSK;
92       break;
93     case SL_WIFI_PMK_CREDENTIAL:
94       // Set the credential type to Pairwise Master Key (PMK)
95       *net_type = SL_NET_WIFI_PMK;
96       break;
97     case SL_WIFI_WEP_CREDENTIAL:
98       // Set the credential type to Wired Equivalent Privacy (WEP)
99       *net_type = SL_NET_WIFI_WEP;
100       break;
101     case SL_WIFI_EAP_CREDENTIAL:
102       // Set the credential type to Extensible Authentication Protocol (EAP)
103       *net_type = SL_NET_EAP_CLIENT_CREDENTIAL;
104       break;
105     default:
106       return SL_STATUS_INVALID_PARAMETER;
107   }
108 
109   return SL_STATUS_OK;
110 }
111 
sl_net_set_credential(sl_net_credential_id_t id,sl_net_credential_type_t type,const void * credential,uint32_t credential_length)112 sl_status_t sl_net_set_credential(sl_net_credential_id_t id,
113                                   sl_net_credential_type_t type,
114                                   const void *credential,
115                                   uint32_t credential_length)
116 {
117   // Check if the credential is invalid parameter
118   if ((NULL == credential) || (0 == credential_length)) {
119     return SL_STATUS_INVALID_PARAMETER;
120   }
121 
122   int group_id                        = 0;
123   int cred_id                         = 0;
124   sl_status_t status                  = 0;
125   sl_wifi_credential_type_t cred_type = 0;
126 
127   if (CRED_TYPE_CERT == sli_si91x_check_cred_type(type)) {
128 #if defined(SLI_SI917) || defined(SLI_SI915)
129     return sl_si91x_set_credential(id, type, credential, credential_length);
130 #else
131     return SL_STATUS_FAIL;
132 #endif
133   }
134 
135   group_id = (id & SL_NET_CREDENTIAL_GROUP_MASK);
136 
137   if (group_id > 0) {
138     cred_id = (SL_NET_USER_CREDENTIAL_ID + (group_id >> 8));
139   } else {
140     group_id = id;
141     cred_id  = id;
142   }
143 
144   switch (group_id) {
145     case SL_NET_DEFAULT_WIFI_CLIENT_CREDENTIAL_ID:
146     case SL_NET_DEFAULT_WIFI_AP_CREDENTIAL_ID:
147     case SL_NET_WIFI_EAP_CLIENT_CREDENTIAL_ID:
148     case SL_NET_WIFI_EAP_SERVER_CREDENTIAL_ID:
149       status = sli_si91x_get_wifi_credential_type(type, &cred_type);
150       VERIFY_STATUS_AND_RETURN(status);
151       break;
152     case SL_NET_USER_CREDENTIAL_ID:
153       status = sli_si91x_get_wifi_credential_type(type, &cred_type);
154       if (status != SL_STATUS_OK) {
155         cred_type = (SL_WIFI_USER_CREDENTIAL | type);
156       }
157       break;
158     case SL_NET_TLS_CLIENT_CREDENTIAL_START:
159     case SL_NET_TLS_SERVER_CREDENTIAL_START:
160     case SL_NET_MQTT_SERVER_CREDENTIAL_START:
161     case SL_NET_MQTT_CLIENT_CREDENTIAL_START:
162     case SL_NET_HTTP_SERVER_CREDENTIAL_START:
163     case SL_NET_HTTP_CLIENT_CREDENTIAL_START:
164       cred_type = (SL_WIFI_USER_CREDENTIAL | type);
165       break;
166 
167     default:
168       return SL_STATUS_FAIL;
169   }
170 
171   return sl_wifi_set_credential(cred_id, cred_type, credential, credential_length);
172 }
173 
sl_net_get_credential(sl_net_credential_id_t id,sl_net_credential_type_t * type,void * credential,uint32_t * credential_length)174 sl_status_t sl_net_get_credential(sl_net_credential_id_t id,
175                                   sl_net_credential_type_t *type,
176                                   void *credential,
177                                   uint32_t *credential_length)
178 {
179   // Check if the credential ID is one of the invalid parameters
180   if ((id == SL_NET_WIFI_EAP_SERVER_CREDENTIAL_ID) || (SL_NET_TLS_CLIENT_CREDENTIAL_START == (id & ~0xff))
181       || (SL_NET_TLS_SERVER_CREDENTIAL_START == (id & ~0xff))) {
182     return SL_STATUS_INVALID_PARAMETER;
183   }
184 
185   // Check if the credential is invalid parameter
186   if ((NULL == credential) || (0 == *credential_length)) {
187     return SL_STATUS_INVALID_PARAMETER;
188   }
189 
190   int group_id                        = 0;
191   int cred_id                         = 0;
192   sl_status_t status                  = 0;
193   sl_wifi_credential_type_t cred_type = 0;
194 
195   group_id = (id & SL_NET_CREDENTIAL_GROUP_MASK);
196 
197   if (group_id > 0) {
198     cred_id = (SL_NET_USER_CREDENTIAL_ID + (group_id >> 8));
199   } else {
200     group_id = id;
201     cred_id  = id;
202   }
203 
204   status = sl_wifi_get_credential(cred_id, &cred_type, credential, credential_length);
205   VERIFY_STATUS_AND_RETURN(status);
206 
207   switch (group_id) {
208     case SL_NET_DEFAULT_WIFI_AP_CREDENTIAL_ID:
209     case SL_NET_DEFAULT_WIFI_CLIENT_CREDENTIAL_ID:
210     case SL_NET_WIFI_EAP_CLIENT_CREDENTIAL_ID:
211     case SL_NET_WIFI_EAP_SERVER_CREDENTIAL_ID:
212       sli_si91x_get_net_credential_type(cred_type, type);
213       break;
214     case SL_NET_USER_CREDENTIAL_ID:
215     case SL_NET_TLS_CLIENT_CREDENTIAL_START:
216     case SL_NET_TLS_SERVER_CREDENTIAL_START:
217     case SL_NET_MQTT_SERVER_CREDENTIAL_START:
218     case SL_NET_MQTT_CLIENT_CREDENTIAL_START:
219     case SL_NET_HTTP_SERVER_CREDENTIAL_START:
220     case SL_NET_HTTP_CLIENT_CREDENTIAL_START:
221       *type = ((~SL_WIFI_USER_CREDENTIAL) & cred_type);
222       break;
223     default:
224       return SL_STATUS_FAIL;
225   }
226   return SL_STATUS_OK;
227 }
228 
sl_net_delete_credential(sl_net_credential_id_t id,sl_net_credential_type_t type)229 sl_status_t sl_net_delete_credential(sl_net_credential_id_t id, sl_net_credential_type_t type)
230 {
231   if (CRED_TYPE_CERT == sli_si91x_check_cred_type(type)) {
232 #if defined(SLI_SI917) || defined(SLI_SI915)
233     return sl_si91x_delete_credential(id, type);
234 #else
235     return SL_STATUS_FAIL;
236 #endif
237   }
238 
239   int group_id = 0;
240   int cred_id  = 0;
241 
242   group_id = (id & SL_NET_CREDENTIAL_GROUP_MASK);
243 
244   if (group_id > 0) {
245     cred_id = (SL_NET_USER_CREDENTIAL_ID + (group_id >> 8));
246   } else {
247     cred_id = id;
248   }
249 
250   return sl_wifi_delete_credential(cred_id);
251 }
252