1 /* 2 * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2022 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 intialization 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 struct wlan_crypto_comp_priv *crypto_priv; 231 232 if (!vdev) { 233 crypto_err("Vdev NULL"); 234 return QDF_STATUS_E_INVAL; 235 } 236 237 crypto_priv = (struct wlan_crypto_comp_priv *) 238 wlan_get_vdev_crypto_obj(vdev); 239 240 if (!crypto_priv) { 241 crypto_err("crypto_priv NULL"); 242 return QDF_STATUS_E_INVAL; 243 } 244 245 wlan_objmgr_vdev_component_obj_detach(vdev, 246 WLAN_UMAC_COMP_CRYPTO, 247 (void *)crypto_priv); 248 249 wlan_crypto_pmksa_flush(&crypto_priv->crypto_params); 250 wlan_crypto_free_key(crypto_priv); 251 qdf_mem_free(crypto_priv); 252 253 return QDF_STATUS_SUCCESS; 254 } 255 256 static QDF_STATUS wlan_crypto_peer_obj_destroy_handler( 257 struct wlan_objmgr_peer *peer, 258 void *arg){ 259 struct wlan_crypto_comp_priv *crypto_priv; 260 261 if (!peer) { 262 crypto_err("Peer NULL"); 263 return QDF_STATUS_E_INVAL; 264 } 265 crypto_priv = (struct wlan_crypto_comp_priv *) 266 wlan_get_peer_crypto_obj(peer); 267 if (!crypto_priv) { 268 crypto_err("crypto_priv NULL"); 269 return QDF_STATUS_E_INVAL; 270 } 271 272 wlan_objmgr_peer_component_obj_detach(peer, 273 WLAN_UMAC_COMP_CRYPTO, 274 (void *)crypto_priv); 275 wlan_crypto_free_key(crypto_priv); 276 qdf_mem_free(crypto_priv); 277 278 return QDF_STATUS_SUCCESS; 279 } 280 /** 281 * __wlan_crypto_init - Init the crypto service with object manager 282 * Called from crypto init context. 283 * 284 * Return: QDF_STATUS_SUCCESS - in case of success 285 */ 286 QDF_STATUS __wlan_crypto_init(void) 287 { 288 QDF_STATUS status = QDF_STATUS_SUCCESS; 289 290 status = wlan_objmgr_register_vdev_create_handler( 291 WLAN_UMAC_COMP_CRYPTO, 292 wlan_crypto_vdev_obj_create_handler, NULL); 293 if (status != QDF_STATUS_SUCCESS) 294 return status; 295 296 status = wlan_objmgr_register_peer_create_handler( 297 WLAN_UMAC_COMP_CRYPTO, 298 wlan_crypto_peer_obj_create_handler, NULL); 299 if (status != QDF_STATUS_SUCCESS) 300 goto err_peer_create; 301 302 status = wlan_objmgr_register_vdev_destroy_handler( 303 WLAN_UMAC_COMP_CRYPTO, 304 wlan_crypto_vdev_obj_destroy_handler, NULL); 305 if (status != QDF_STATUS_SUCCESS) 306 goto err_vdev_delete; 307 308 status = wlan_objmgr_register_peer_destroy_handler( 309 WLAN_UMAC_COMP_CRYPTO, 310 wlan_crypto_peer_obj_destroy_handler, NULL); 311 if (status != QDF_STATUS_SUCCESS) 312 goto err_peer_delete; 313 314 goto register_success; 315 err_peer_delete: 316 wlan_objmgr_unregister_vdev_destroy_handler(WLAN_UMAC_COMP_CRYPTO, 317 wlan_crypto_vdev_obj_destroy_handler, NULL); 318 err_vdev_delete: 319 wlan_objmgr_unregister_peer_create_handler(WLAN_UMAC_COMP_CRYPTO, 320 wlan_crypto_peer_obj_create_handler, NULL); 321 err_peer_create: 322 wlan_objmgr_unregister_vdev_create_handler(WLAN_UMAC_COMP_CRYPTO, 323 wlan_crypto_vdev_obj_create_handler, NULL); 324 325 register_success: 326 return status; 327 } 328 329 /** 330 * __wlan_crypto_deinit - Deinit the crypto service with object manager 331 * Called from crypto context. 332 * 333 * Return: QDF_STATUS_SUCCESS - in case of success 334 */ 335 QDF_STATUS __wlan_crypto_deinit(void) 336 { 337 338 if (wlan_objmgr_unregister_vdev_create_handler(WLAN_UMAC_COMP_CRYPTO, 339 wlan_crypto_vdev_obj_create_handler, NULL) 340 != QDF_STATUS_SUCCESS) { 341 return QDF_STATUS_E_FAILURE; 342 } 343 344 if (wlan_objmgr_unregister_peer_create_handler(WLAN_UMAC_COMP_CRYPTO, 345 wlan_crypto_peer_obj_create_handler, NULL) 346 != QDF_STATUS_SUCCESS) { 347 return QDF_STATUS_E_FAILURE; 348 } 349 350 if (wlan_objmgr_unregister_vdev_destroy_handler(WLAN_UMAC_COMP_CRYPTO, 351 wlan_crypto_vdev_obj_destroy_handler, NULL) 352 != QDF_STATUS_SUCCESS) { 353 return QDF_STATUS_E_FAILURE; 354 } 355 356 if (wlan_objmgr_unregister_peer_destroy_handler(WLAN_UMAC_COMP_CRYPTO, 357 wlan_crypto_peer_obj_destroy_handler, NULL) 358 != QDF_STATUS_SUCCESS) { 359 return QDF_STATUS_E_FAILURE; 360 } 361 362 return QDF_STATUS_SUCCESS; 363 } 364