1 /* 2 * Copyright (c) 2017-2018 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 #include "wlan_crypto_fils_api.h" 38 39 40 extern const struct wlan_crypto_cipher *wep_register(void); 41 extern const struct wlan_crypto_cipher *tkip_register(void); 42 extern const struct wlan_crypto_cipher *ccmp_register(void); 43 extern const struct wlan_crypto_cipher *ccmp256_register(void); 44 extern const struct wlan_crypto_cipher *gcmp_register(void); 45 extern const struct wlan_crypto_cipher *gcmp256_register(void); 46 extern const struct wlan_crypto_cipher *wapi_register(void); 47 48 extern const struct wlan_crypto_cipher 49 *wlan_crypto_cipher_ops[WLAN_CRYPTO_CIPHER_MAX]; 50 51 static QDF_STATUS wlan_crypto_register_all_ciphers( 52 struct wlan_crypto_params *crypto_param) 53 { 54 55 if (HAS_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_WEP)) { 56 wlan_crypto_cipher_ops[WLAN_CRYPTO_CIPHER_WEP] 57 = wep_register(); 58 } 59 if (HAS_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_TKIP_MIC)) { 60 wlan_crypto_cipher_ops[WLAN_CRYPTO_CIPHER_TKIP] 61 = tkip_register(); 62 } 63 if (HAS_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_AES)) { 64 wlan_crypto_cipher_ops[WLAN_CRYPTO_CIPHER_AES_CCM] 65 = ccmp_register(); 66 wlan_crypto_cipher_ops[WLAN_CRYPTO_CIPHER_AES_CCM_256] 67 = ccmp256_register(); 68 wlan_crypto_cipher_ops[WLAN_CRYPTO_CIPHER_AES_GCM] 69 = gcmp_register(); 70 wlan_crypto_cipher_ops[WLAN_CRYPTO_CIPHER_AES_GCM_256] 71 = gcmp256_register(); 72 } 73 if (HAS_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_WAPI_SMS4)) { 74 wlan_crypto_cipher_ops[WLAN_CRYPTO_CIPHER_WAPI_SMS4] 75 = wapi_register(); 76 } 77 if (HAS_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_FILS_AEAD)) { 78 wlan_crypto_cipher_ops[WLAN_CRYPTO_CIPHER_FILS_AEAD] 79 = fils_register(); 80 } 81 82 return QDF_STATUS_SUCCESS; 83 } 84 85 static QDF_STATUS wlan_crypto_psoc_obj_create_handler( 86 struct wlan_objmgr_psoc *psoc, 87 void *arg) 88 { 89 return QDF_STATUS_SUCCESS; 90 } 91 92 static QDF_STATUS wlan_crypto_pdev_obj_create_handler( 93 struct wlan_objmgr_pdev *pdev, 94 void *arg) 95 { 96 return QDF_STATUS_SUCCESS; 97 } 98 99 static QDF_STATUS wlan_crypto_vdev_obj_create_handler( 100 struct wlan_objmgr_vdev *vdev, 101 void *arg) 102 { 103 struct wlan_crypto_comp_priv *crypto_priv; 104 struct wlan_objmgr_pdev *pdev; 105 struct wlan_crypto_params *crypto_param; 106 QDF_STATUS status; 107 108 if (!vdev) 109 return QDF_STATUS_E_INVAL; 110 111 crypto_priv = qdf_mem_malloc(sizeof(struct wlan_crypto_comp_priv)); 112 if (!crypto_priv) 113 return QDF_STATUS_E_NOMEM; 114 115 crypto_param = &(crypto_priv->crypto_params); 116 117 RESET_AUTHMODE(crypto_param); 118 RESET_UCAST_CIPHERS(crypto_param); 119 RESET_MCAST_CIPHERS(crypto_param); 120 RESET_MGMT_CIPHERS(crypto_param); 121 RESET_KEY_MGMT(crypto_param); 122 RESET_CIPHER_CAP(crypto_param); 123 124 pdev = wlan_vdev_get_pdev(vdev); 125 wlan_pdev_obj_lock(pdev); 126 if (wlan_pdev_nif_fw_cap_get(pdev, WLAN_SOC_C_WEP)) 127 SET_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_WEP); 128 if (wlan_pdev_nif_fw_cap_get(pdev, WLAN_SOC_C_TKIP)) 129 SET_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_TKIP_MIC); 130 if (wlan_pdev_nif_fw_cap_get(pdev, WLAN_SOC_C_AES)) { 131 SET_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_AES); 132 SET_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_CCM256); 133 SET_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_GCM); 134 SET_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_GCM_256); 135 } 136 if (wlan_pdev_nif_fw_cap_get(pdev, WLAN_SOC_C_CKIP)) 137 SET_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_CKIP); 138 if (wlan_pdev_nif_fw_cap_get(pdev, WLAN_SOC_C_WAPI)) 139 SET_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_WAPI_SMS4); 140 SET_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_FILS_AEAD); 141 wlan_pdev_obj_unlock(pdev); 142 /* update the crypto cipher table based on the fw caps*/ 143 /* update the fw_caps into ciphercaps then attach to objmgr*/ 144 wlan_crypto_register_all_ciphers(crypto_param); 145 146 status = wlan_objmgr_vdev_component_obj_attach(vdev, 147 WLAN_UMAC_COMP_CRYPTO, 148 (void *)crypto_priv, 149 QDF_STATUS_SUCCESS); 150 if (status != QDF_STATUS_SUCCESS) 151 qdf_mem_free(crypto_priv); 152 153 return status; 154 } 155 156 static QDF_STATUS wlan_crypto_peer_obj_create_handler( 157 struct wlan_objmgr_peer *peer, 158 void *arg) 159 { 160 struct wlan_crypto_comp_priv *crypto_priv; 161 struct wlan_crypto_params *crypto_param; 162 QDF_STATUS status; 163 164 if (!peer) 165 return QDF_STATUS_E_INVAL; 166 167 crypto_priv = qdf_mem_malloc(sizeof(struct wlan_crypto_comp_priv)); 168 if (!crypto_priv) 169 return QDF_STATUS_E_NOMEM; 170 171 status = wlan_objmgr_peer_component_obj_attach(peer, 172 WLAN_UMAC_COMP_CRYPTO, (void *)crypto_priv, 173 QDF_STATUS_SUCCESS); 174 175 if (status == QDF_STATUS_SUCCESS) { 176 crypto_param = &crypto_priv->crypto_params; 177 RESET_AUTHMODE(crypto_param); 178 RESET_UCAST_CIPHERS(crypto_param); 179 RESET_MCAST_CIPHERS(crypto_param); 180 RESET_MGMT_CIPHERS(crypto_param); 181 RESET_KEY_MGMT(crypto_param); 182 RESET_CIPHER_CAP(crypto_param); 183 if (wlan_vdev_get_selfpeer(peer->peer_objmgr.vdev) != peer) { 184 wlan_crypto_set_peer_wep_keys( 185 wlan_peer_get_vdev(peer), peer); 186 } 187 } else { 188 qdf_print("%s[%d] peer obj failed status %d\n", 189 __func__, __LINE__, status); 190 qdf_mem_free(crypto_priv); 191 } 192 193 return status; 194 } 195 196 static QDF_STATUS wlan_crypto_psoc_obj_destroy_handler( 197 struct wlan_objmgr_psoc *psoc, 198 void *arg){ 199 200 return QDF_STATUS_COMP_DISABLED; 201 } 202 203 static QDF_STATUS wlan_crypto_pdev_obj_destroy_handler( 204 struct wlan_objmgr_pdev *pdev, 205 void *arg){ 206 207 return QDF_STATUS_SUCCESS; 208 } 209 210 static void wlan_crypto_free_key(struct wlan_crypto_comp_priv *crypto_priv) 211 { 212 uint8_t i; 213 214 if (!crypto_priv) { 215 qdf_print("%s[%d] crypto_priv NULL\n", __func__, __LINE__); 216 return; 217 } 218 219 for (i = 0; i < WLAN_CRYPTO_MAXKEYIDX; i++) { 220 if (crypto_priv->key[i]) { 221 qdf_mem_free(crypto_priv->key[i]); 222 crypto_priv->key[i] = NULL; 223 } 224 } 225 226 for (i = 0; i < WLAN_CRYPTO_MAXIGTKKEYIDX; i++) { 227 if (crypto_priv->igtk_key[i]) { 228 qdf_mem_free(crypto_priv->igtk_key[i]); 229 crypto_priv->igtk_key[i] = NULL; 230 } 231 } 232 233 } 234 235 static QDF_STATUS wlan_crypto_vdev_obj_destroy_handler( 236 struct wlan_objmgr_vdev *vdev, 237 void *arg){ 238 struct wlan_crypto_comp_priv *crypto_priv; 239 240 if (!vdev) { 241 qdf_print("%s[%d] Vdev NULL\n", __func__, __LINE__); 242 return QDF_STATUS_E_INVAL; 243 } 244 245 crypto_priv = (struct wlan_crypto_comp_priv *) 246 wlan_get_vdev_crypto_obj(vdev); 247 248 if (!crypto_priv) { 249 qdf_print("%s[%d] crypto_priv NULL\n", __func__, __LINE__); 250 return QDF_STATUS_E_INVAL; 251 } 252 wlan_objmgr_vdev_component_obj_detach(vdev, 253 WLAN_UMAC_COMP_CRYPTO, 254 (void *)crypto_priv); 255 wlan_crypto_free_key(crypto_priv); 256 qdf_mem_free(crypto_priv); 257 258 return QDF_STATUS_SUCCESS; 259 } 260 261 static QDF_STATUS wlan_crypto_peer_obj_destroy_handler( 262 struct wlan_objmgr_peer *peer, 263 void *arg){ 264 struct wlan_crypto_comp_priv *crypto_priv; 265 266 if (!peer) { 267 qdf_print("%s[%d] Peer NULL\n", __func__, __LINE__); 268 return QDF_STATUS_E_INVAL; 269 } 270 crypto_priv = (struct wlan_crypto_comp_priv *) 271 wlan_get_peer_crypto_obj(peer); 272 if (!crypto_priv) { 273 qdf_print("%s[%d] crypto_priv NULL\n", __func__, __LINE__); 274 return QDF_STATUS_E_INVAL; 275 } 276 277 wlan_objmgr_peer_component_obj_detach(peer, 278 WLAN_UMAC_COMP_CRYPTO, 279 (void *)crypto_priv); 280 wlan_crypto_free_key(crypto_priv); 281 qdf_mem_free(crypto_priv); 282 283 return QDF_STATUS_SUCCESS; 284 } 285 /** 286 * __wlan_crypto_init - Init the crypto service with object manager 287 * Called from crypto init context. 288 * 289 * Return: QDF_STATUS_SUCCESS - in case of success 290 */ 291 QDF_STATUS __wlan_crypto_init(void) 292 { 293 QDF_STATUS status = QDF_STATUS_SUCCESS; 294 295 status = wlan_objmgr_register_vdev_create_handler( 296 WLAN_UMAC_COMP_CRYPTO, 297 wlan_crypto_vdev_obj_create_handler, NULL); 298 if (status != QDF_STATUS_SUCCESS) 299 goto err_vdev_create; 300 301 status = wlan_objmgr_register_peer_create_handler( 302 WLAN_UMAC_COMP_CRYPTO, 303 wlan_crypto_peer_obj_create_handler, NULL); 304 if (status != QDF_STATUS_SUCCESS) 305 goto err_peer_create; 306 307 status = wlan_objmgr_register_vdev_destroy_handler( 308 WLAN_UMAC_COMP_CRYPTO, 309 wlan_crypto_vdev_obj_destroy_handler, NULL); 310 if (status != QDF_STATUS_SUCCESS) 311 goto err_vdev_delete; 312 313 status = wlan_objmgr_register_peer_destroy_handler( 314 WLAN_UMAC_COMP_CRYPTO, 315 wlan_crypto_peer_obj_destroy_handler, NULL); 316 if (status != QDF_STATUS_SUCCESS) 317 goto err_peer_delete; 318 319 goto register_success; 320 err_peer_delete: 321 wlan_objmgr_unregister_vdev_destroy_handler(WLAN_UMAC_COMP_CRYPTO, 322 wlan_crypto_vdev_obj_destroy_handler, NULL); 323 err_vdev_delete: 324 wlan_objmgr_unregister_peer_create_handler(WLAN_UMAC_COMP_CRYPTO, 325 wlan_crypto_peer_obj_create_handler, NULL); 326 err_peer_create: 327 wlan_objmgr_unregister_vdev_create_handler(WLAN_UMAC_COMP_CRYPTO, 328 wlan_crypto_vdev_obj_create_handler, NULL); 329 err_vdev_create: 330 wlan_objmgr_unregister_pdev_create_handler(WLAN_UMAC_COMP_CRYPTO, 331 wlan_crypto_pdev_obj_create_handler, NULL); 332 register_success: 333 return status; 334 } 335 336 /** 337 * __wlan_crypto_deinit - Deinit the crypto service with object manager 338 * Called from crypto context. 339 * 340 * Return: QDF_STATUS_SUCCESS - in case of success 341 */ 342 QDF_STATUS __wlan_crypto_deinit(void) 343 { 344 345 if (wlan_objmgr_unregister_vdev_create_handler(WLAN_UMAC_COMP_CRYPTO, 346 wlan_crypto_vdev_obj_create_handler, NULL) 347 != QDF_STATUS_SUCCESS) { 348 return QDF_STATUS_E_FAILURE; 349 } 350 351 if (wlan_objmgr_unregister_peer_create_handler(WLAN_UMAC_COMP_CRYPTO, 352 wlan_crypto_peer_obj_create_handler, NULL) 353 != QDF_STATUS_SUCCESS) { 354 return QDF_STATUS_E_FAILURE; 355 } 356 357 if (wlan_objmgr_unregister_vdev_destroy_handler(WLAN_UMAC_COMP_CRYPTO, 358 wlan_crypto_vdev_obj_destroy_handler, NULL) 359 != QDF_STATUS_SUCCESS) { 360 return QDF_STATUS_E_FAILURE; 361 } 362 363 if (wlan_objmgr_unregister_peer_destroy_handler(WLAN_UMAC_COMP_CRYPTO, 364 wlan_crypto_peer_obj_destroy_handler, NULL) 365 != QDF_STATUS_SUCCESS) { 366 return QDF_STATUS_E_FAILURE; 367 } 368 369 return QDF_STATUS_SUCCESS; 370 } 371