1 /* 2 * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for 6 * any purpose with or without fee is hereby granted, provided that the 7 * above copyright notice and this permission notice appear in all 8 * copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 /** 21 * DOC: Public API initialization of crypto service with object manager 22 */ 23 #include <qdf_types.h> 24 #include <wlan_cmn.h> 25 #include <wlan_objmgr_cmn.h> 26 27 #include <wlan_objmgr_global_obj.h> 28 #include <wlan_objmgr_psoc_obj.h> 29 #include <wlan_objmgr_pdev_obj.h> 30 #include <wlan_objmgr_vdev_obj.h> 31 #include <wlan_objmgr_peer_obj.h> 32 33 #include "wlan_crypto_global_def.h" 34 #include "wlan_crypto_global_api.h" 35 #include "wlan_crypto_def_i.h" 36 #include "wlan_crypto_main_i.h" 37 #include "wlan_crypto_obj_mgr_i.h" 38 #ifdef WLAN_CRYPTO_SUPPORT_FILS 39 #include "wlan_crypto_fils_api.h" 40 #endif 41 42 43 extern const struct wlan_crypto_cipher 44 *wlan_crypto_cipher_ops[WLAN_CRYPTO_CIPHER_MAX]; 45 46 static QDF_STATUS wlan_crypto_register_all_ciphers( 47 struct wlan_crypto_params *crypto_param) 48 { 49 50 if (HAS_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_WEP)) { 51 wlan_crypto_cipher_ops[WLAN_CRYPTO_CIPHER_WEP] 52 = wep_register(); 53 } 54 if (HAS_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_TKIP_MIC)) { 55 wlan_crypto_cipher_ops[WLAN_CRYPTO_CIPHER_TKIP] 56 = tkip_register(); 57 } 58 if (HAS_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_AES)) { 59 wlan_crypto_cipher_ops[WLAN_CRYPTO_CIPHER_AES_CCM] 60 = ccmp_register(); 61 wlan_crypto_cipher_ops[WLAN_CRYPTO_CIPHER_AES_CCM_256] 62 = ccmp256_register(); 63 wlan_crypto_cipher_ops[WLAN_CRYPTO_CIPHER_AES_GCM] 64 = gcmp_register(); 65 wlan_crypto_cipher_ops[WLAN_CRYPTO_CIPHER_AES_GCM_256] 66 = gcmp256_register(); 67 } 68 if (HAS_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_WAPI_SMS4)) { 69 wlan_crypto_cipher_ops[WLAN_CRYPTO_CIPHER_WAPI_SMS4] 70 = wapi_register(); 71 } 72 if (HAS_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_FILS_AEAD)) { 73 wlan_crypto_cipher_ops[WLAN_CRYPTO_CIPHER_FILS_AEAD] 74 = fils_register(); 75 } 76 77 return QDF_STATUS_SUCCESS; 78 } 79 80 static QDF_STATUS wlan_crypto_vdev_obj_create_handler( 81 struct wlan_objmgr_vdev *vdev, 82 void *arg) 83 { 84 struct wlan_crypto_comp_priv *crypto_priv; 85 struct wlan_objmgr_pdev *pdev; 86 struct wlan_crypto_params *crypto_param; 87 QDF_STATUS status; 88 89 if (!vdev) 90 return QDF_STATUS_E_INVAL; 91 92 crypto_priv = qdf_mem_malloc(sizeof(struct wlan_crypto_comp_priv)); 93 if (!crypto_priv) 94 return QDF_STATUS_E_NOMEM; 95 96 crypto_param = &(crypto_priv->crypto_params); 97 98 RESET_AUTHMODE(crypto_param); 99 RESET_UCAST_CIPHERS(crypto_param); 100 RESET_MCAST_CIPHERS(crypto_param); 101 RESET_MGMT_CIPHERS(crypto_param); 102 RESET_KEY_MGMT(crypto_param); 103 RESET_CIPHER_CAP(crypto_param); 104 105 pdev = wlan_vdev_get_pdev(vdev); 106 wlan_pdev_obj_lock(pdev); 107 if (wlan_pdev_nif_fw_cap_get(pdev, WLAN_SOC_C_WEP)) 108 SET_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_WEP); 109 if (wlan_pdev_nif_fw_cap_get(pdev, WLAN_SOC_C_TKIP)) 110 SET_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_TKIP_MIC); 111 if (wlan_pdev_nif_fw_cap_get(pdev, WLAN_SOC_C_AES)) { 112 SET_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_AES); 113 SET_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_CCM256); 114 SET_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_GCM); 115 SET_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_GCM_256); 116 } 117 if (wlan_pdev_nif_fw_cap_get(pdev, WLAN_SOC_C_CKIP)) 118 SET_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_CKIP); 119 if (wlan_pdev_nif_fw_cap_get(pdev, WLAN_SOC_C_WAPI)) 120 SET_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_WAPI_SMS4); 121 SET_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_FILS_AEAD); 122 wlan_pdev_obj_unlock(pdev); 123 /* update the crypto cipher table based on the fw caps*/ 124 /* update the fw_caps into ciphercaps then attach to objmgr*/ 125 wlan_crypto_register_all_ciphers(crypto_param); 126 127 status = wlan_objmgr_vdev_component_obj_attach(vdev, 128 WLAN_UMAC_COMP_CRYPTO, 129 (void *)crypto_priv, 130 QDF_STATUS_SUCCESS); 131 if (status != QDF_STATUS_SUCCESS) 132 qdf_mem_free(crypto_priv); 133 134 return status; 135 } 136 137 static QDF_STATUS wlan_crypto_peer_obj_create_handler( 138 struct wlan_objmgr_peer *peer, 139 void *arg) 140 { 141 struct wlan_crypto_comp_priv *crypto_priv; 142 struct wlan_crypto_params *crypto_param; 143 QDF_STATUS status; 144 145 if (!peer) 146 return QDF_STATUS_E_INVAL; 147 148 crypto_priv = qdf_mem_malloc(sizeof(struct wlan_crypto_comp_priv)); 149 if (!crypto_priv) 150 return QDF_STATUS_E_NOMEM; 151 152 status = wlan_objmgr_peer_component_obj_attach(peer, 153 WLAN_UMAC_COMP_CRYPTO, (void *)crypto_priv, 154 QDF_STATUS_SUCCESS); 155 156 if (status == QDF_STATUS_SUCCESS) { 157 crypto_param = &crypto_priv->crypto_params; 158 RESET_AUTHMODE(crypto_param); 159 RESET_UCAST_CIPHERS(crypto_param); 160 RESET_MCAST_CIPHERS(crypto_param); 161 RESET_MGMT_CIPHERS(crypto_param); 162 RESET_KEY_MGMT(crypto_param); 163 RESET_CIPHER_CAP(crypto_param); 164 if (wlan_vdev_get_selfpeer(peer->peer_objmgr.vdev) != peer) { 165 wlan_crypto_set_peer_wep_keys( 166 wlan_peer_get_vdev(peer), peer); 167 } 168 } else { 169 crypto_err("peer obj failed status %d", status); 170 qdf_mem_free(crypto_priv); 171 } 172 173 return status; 174 } 175 176 static void wlan_crypto_free_key(struct wlan_crypto_comp_priv *crypto_priv) 177 { 178 uint8_t i; 179 180 if (!crypto_priv) { 181 crypto_err("crypto_priv NULL"); 182 return; 183 } 184 185 for (i = 0; i < WLAN_CRYPTO_MAX_VLANKEYIX; i++) { 186 if (crypto_priv->key[i]) { 187 qdf_mem_free(crypto_priv->key[i]); 188 crypto_priv->key[i] = NULL; 189 } 190 } 191 192 for (i = 0; i < WLAN_CRYPTO_MAXIGTKKEYIDX; i++) { 193 if (crypto_priv->igtk_key[i]) { 194 qdf_mem_free(crypto_priv->igtk_key[i]); 195 crypto_priv->igtk_key[i] = NULL; 196 } 197 } 198 199 for (i = 0; i < WLAN_CRYPTO_MAXBIGTKKEYIDX; i++) { 200 if (crypto_priv->bigtk_key[i]) { 201 qdf_mem_free(crypto_priv->bigtk_key[i]); 202 crypto_priv->bigtk_key[i] = NULL; 203 } 204 } 205 /* Reset All key index as well */ 206 crypto_priv->def_tx_keyid = 0; 207 crypto_priv->def_igtk_tx_keyid = 0; 208 crypto_priv->def_bigtk_tx_keyid = 0; 209 } 210 211 #ifdef CRYPTO_SET_KEY_CONVERGED 212 void wlan_crypto_free_vdev_key(struct wlan_objmgr_vdev *vdev) 213 { 214 struct wlan_crypto_comp_priv *crypto_priv; 215 216 crypto_debug("free key for vdev %d", wlan_vdev_get_id(vdev)); 217 crypto_priv = wlan_get_vdev_crypto_obj(vdev); 218 if (!crypto_priv) { 219 crypto_err("crypto_priv NULL"); 220 return; 221 } 222 223 wlan_crypto_free_key(crypto_priv); 224 } 225 #endif 226 227 static QDF_STATUS wlan_crypto_vdev_obj_destroy_handler( 228 struct wlan_objmgr_vdev *vdev, 229 void *arg) 230 { 231 struct wlan_crypto_comp_priv *crypto_priv; 232 233 if (!vdev) { 234 crypto_err("Vdev NULL"); 235 return QDF_STATUS_E_INVAL; 236 } 237 238 crypto_priv = (struct wlan_crypto_comp_priv *) 239 wlan_get_vdev_crypto_obj(vdev); 240 241 if (!crypto_priv) { 242 crypto_err("crypto_priv NULL"); 243 return QDF_STATUS_E_INVAL; 244 } 245 246 wlan_objmgr_vdev_component_obj_detach(vdev, 247 WLAN_UMAC_COMP_CRYPTO, 248 (void *)crypto_priv); 249 250 wlan_crypto_pmksa_flush(&crypto_priv->crypto_params); 251 wlan_crypto_free_key(crypto_priv); 252 qdf_mem_free(crypto_priv); 253 254 return QDF_STATUS_SUCCESS; 255 } 256 257 static QDF_STATUS wlan_crypto_peer_obj_destroy_handler( 258 struct wlan_objmgr_peer *peer, 259 void *arg) 260 { 261 struct wlan_crypto_comp_priv *crypto_priv; 262 263 if (!peer) { 264 crypto_err("Peer NULL"); 265 return QDF_STATUS_E_INVAL; 266 } 267 crypto_priv = (struct wlan_crypto_comp_priv *) 268 wlan_get_peer_crypto_obj(peer); 269 if (!crypto_priv) { 270 crypto_err("crypto_priv NULL"); 271 return QDF_STATUS_E_INVAL; 272 } 273 274 wlan_objmgr_peer_component_obj_detach(peer, 275 WLAN_UMAC_COMP_CRYPTO, 276 (void *)crypto_priv); 277 wlan_crypto_free_key(crypto_priv); 278 qdf_mem_free(crypto_priv); 279 280 return QDF_STATUS_SUCCESS; 281 } 282 283 QDF_STATUS __wlan_crypto_init(void) 284 { 285 QDF_STATUS status = QDF_STATUS_SUCCESS; 286 287 status = wlan_objmgr_register_vdev_create_handler( 288 WLAN_UMAC_COMP_CRYPTO, 289 wlan_crypto_vdev_obj_create_handler, NULL); 290 if (status != QDF_STATUS_SUCCESS) 291 return status; 292 293 status = wlan_objmgr_register_peer_create_handler( 294 WLAN_UMAC_COMP_CRYPTO, 295 wlan_crypto_peer_obj_create_handler, NULL); 296 if (status != QDF_STATUS_SUCCESS) 297 goto err_peer_create; 298 299 status = wlan_objmgr_register_vdev_destroy_handler( 300 WLAN_UMAC_COMP_CRYPTO, 301 wlan_crypto_vdev_obj_destroy_handler, NULL); 302 if (status != QDF_STATUS_SUCCESS) 303 goto err_vdev_delete; 304 305 status = wlan_objmgr_register_peer_destroy_handler( 306 WLAN_UMAC_COMP_CRYPTO, 307 wlan_crypto_peer_obj_destroy_handler, NULL); 308 if (status != QDF_STATUS_SUCCESS) 309 goto err_peer_delete; 310 311 goto register_success; 312 err_peer_delete: 313 wlan_objmgr_unregister_vdev_destroy_handler(WLAN_UMAC_COMP_CRYPTO, 314 wlan_crypto_vdev_obj_destroy_handler, NULL); 315 err_vdev_delete: 316 wlan_objmgr_unregister_peer_create_handler(WLAN_UMAC_COMP_CRYPTO, 317 wlan_crypto_peer_obj_create_handler, NULL); 318 err_peer_create: 319 wlan_objmgr_unregister_vdev_create_handler(WLAN_UMAC_COMP_CRYPTO, 320 wlan_crypto_vdev_obj_create_handler, NULL); 321 322 register_success: 323 return status; 324 } 325 326 QDF_STATUS __wlan_crypto_deinit(void) 327 { 328 329 if (wlan_objmgr_unregister_vdev_create_handler(WLAN_UMAC_COMP_CRYPTO, 330 wlan_crypto_vdev_obj_create_handler, NULL) 331 != QDF_STATUS_SUCCESS) { 332 return QDF_STATUS_E_FAILURE; 333 } 334 335 if (wlan_objmgr_unregister_peer_create_handler(WLAN_UMAC_COMP_CRYPTO, 336 wlan_crypto_peer_obj_create_handler, NULL) 337 != QDF_STATUS_SUCCESS) { 338 return QDF_STATUS_E_FAILURE; 339 } 340 341 if (wlan_objmgr_unregister_vdev_destroy_handler(WLAN_UMAC_COMP_CRYPTO, 342 wlan_crypto_vdev_obj_destroy_handler, NULL) 343 != QDF_STATUS_SUCCESS) { 344 return QDF_STATUS_E_FAILURE; 345 } 346 347 if (wlan_objmgr_unregister_peer_destroy_handler(WLAN_UMAC_COMP_CRYPTO, 348 wlan_crypto_peer_obj_destroy_handler, NULL) 349 != QDF_STATUS_SUCCESS) { 350 return QDF_STATUS_E_FAILURE; 351 } 352 353 return QDF_STATUS_SUCCESS; 354 } 355