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