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 pdev = wlan_vdev_get_pdev(vdev); 117 wlan_pdev_obj_lock(pdev); 118 if (wlan_pdev_nif_fw_cap_get(pdev, WLAN_SOC_C_WEP)) 119 SET_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_WEP); 120 if (wlan_pdev_nif_fw_cap_get(pdev, WLAN_SOC_C_TKIP)) 121 SET_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_TKIP_MIC); 122 if (wlan_pdev_nif_fw_cap_get(pdev, WLAN_SOC_C_AES)) { 123 SET_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_AES); 124 SET_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_CCM256); 125 SET_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_GCM); 126 SET_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_GCM_256); 127 } 128 if (wlan_pdev_nif_fw_cap_get(pdev, WLAN_SOC_C_CKIP)) 129 SET_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_CKIP); 130 if (wlan_pdev_nif_fw_cap_get(pdev, WLAN_SOC_C_WAPI)) 131 SET_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_WAPI_SMS4); 132 SET_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_FILS_AEAD); 133 wlan_pdev_obj_unlock(pdev); 134 /* update the crypto cipher table based on the fw caps*/ 135 /* update the fw_caps into ciphercaps then attach to objmgr*/ 136 wlan_crypto_register_all_ciphers(crypto_param); 137 138 status = wlan_objmgr_vdev_component_obj_attach(vdev, 139 WLAN_UMAC_COMP_CRYPTO, 140 (void *)crypto_priv, 141 QDF_STATUS_SUCCESS); 142 if (status != QDF_STATUS_SUCCESS) 143 qdf_mem_free(crypto_priv); 144 145 return status; 146 } 147 148 static QDF_STATUS wlan_crypto_peer_obj_create_handler( 149 struct wlan_objmgr_peer *peer, 150 void *arg) 151 { 152 struct wlan_crypto_comp_priv *crypto_priv; 153 QDF_STATUS status; 154 155 if (!peer) 156 return QDF_STATUS_E_INVAL; 157 158 crypto_priv = qdf_mem_malloc(sizeof(struct wlan_crypto_comp_priv)); 159 if (!crypto_priv) 160 return QDF_STATUS_E_NOMEM; 161 162 status = wlan_objmgr_peer_component_obj_attach(peer, 163 WLAN_UMAC_COMP_CRYPTO, (void *)crypto_priv, 164 QDF_STATUS_SUCCESS); 165 166 if (status == QDF_STATUS_SUCCESS) { 167 if (wlan_vdev_get_selfpeer(peer->peer_objmgr.vdev) != peer) { 168 wlan_crypto_set_peer_wep_keys( 169 wlan_peer_get_vdev(peer), peer); 170 } 171 } else { 172 qdf_print("%s[%d] peer obj failed status %d\n", 173 __func__, __LINE__, status); 174 qdf_mem_free(crypto_priv); 175 } 176 177 return status; 178 } 179 180 static QDF_STATUS wlan_crypto_psoc_obj_destroy_handler( 181 struct wlan_objmgr_psoc *psoc, 182 void *arg){ 183 184 return QDF_STATUS_COMP_DISABLED; 185 } 186 187 static QDF_STATUS wlan_crypto_pdev_obj_destroy_handler( 188 struct wlan_objmgr_pdev *pdev, 189 void *arg){ 190 191 return QDF_STATUS_SUCCESS; 192 } 193 194 static void wlan_crypto_free_key(struct wlan_crypto_comp_priv *crypto_priv) 195 { 196 uint8_t i; 197 198 if (!crypto_priv) { 199 qdf_print("%s[%d] crypto_priv NULL\n", __func__, __LINE__); 200 return; 201 } 202 203 for (i = 0; i < WLAN_CRYPTO_MAXKEYIDX; i++) { 204 if (crypto_priv->key[i]) { 205 qdf_mem_free(crypto_priv->key[i]); 206 crypto_priv->key[i] = NULL; 207 } 208 } 209 210 for (i = 0; i < WLAN_CRYPTO_MAXIGTKKEYIDX; i++) { 211 if (crypto_priv->igtk_key[i]) { 212 qdf_mem_free(crypto_priv->igtk_key[i]); 213 crypto_priv->igtk_key[i] = NULL; 214 } 215 } 216 217 } 218 219 static QDF_STATUS wlan_crypto_vdev_obj_destroy_handler( 220 struct wlan_objmgr_vdev *vdev, 221 void *arg){ 222 struct wlan_crypto_comp_priv *crypto_priv; 223 224 if (!vdev) { 225 qdf_print("%s[%d] Vdev NULL\n", __func__, __LINE__); 226 return QDF_STATUS_E_INVAL; 227 } 228 229 crypto_priv = (struct wlan_crypto_comp_priv *) 230 wlan_get_vdev_crypto_obj(vdev); 231 232 if (!crypto_priv) { 233 qdf_print("%s[%d] crypto_priv NULL\n", __func__, __LINE__); 234 return QDF_STATUS_E_INVAL; 235 } 236 wlan_objmgr_vdev_component_obj_detach(vdev, 237 WLAN_UMAC_COMP_CRYPTO, 238 (void *)crypto_priv); 239 wlan_crypto_free_key(crypto_priv); 240 qdf_mem_free(crypto_priv); 241 242 return QDF_STATUS_SUCCESS; 243 } 244 245 static QDF_STATUS wlan_crypto_peer_obj_destroy_handler( 246 struct wlan_objmgr_peer *peer, 247 void *arg){ 248 struct wlan_crypto_comp_priv *crypto_priv; 249 250 if (!peer) { 251 qdf_print("%s[%d] Peer NULL\n", __func__, __LINE__); 252 return QDF_STATUS_E_INVAL; 253 } 254 crypto_priv = (struct wlan_crypto_comp_priv *) 255 wlan_get_peer_crypto_obj(peer); 256 if (!crypto_priv) { 257 qdf_print("%s[%d] crypto_priv NULL\n", __func__, __LINE__); 258 return QDF_STATUS_E_INVAL; 259 } 260 261 wlan_objmgr_peer_component_obj_detach(peer, 262 WLAN_UMAC_COMP_CRYPTO, 263 (void *)crypto_priv); 264 wlan_crypto_free_key(crypto_priv); 265 qdf_mem_free(crypto_priv); 266 267 return QDF_STATUS_SUCCESS; 268 } 269 /** 270 * __wlan_crypto_init - Init the crypto service with object manager 271 * Called from crypto init context. 272 * 273 * Return: QDF_STATUS_SUCCESS - in case of success 274 */ 275 QDF_STATUS __wlan_crypto_init(void) 276 { 277 QDF_STATUS status = QDF_STATUS_SUCCESS; 278 279 status = wlan_objmgr_register_vdev_create_handler( 280 WLAN_UMAC_COMP_CRYPTO, 281 wlan_crypto_vdev_obj_create_handler, NULL); 282 if (status != QDF_STATUS_SUCCESS) 283 goto err_vdev_create; 284 285 status = wlan_objmgr_register_peer_create_handler( 286 WLAN_UMAC_COMP_CRYPTO, 287 wlan_crypto_peer_obj_create_handler, NULL); 288 if (status != QDF_STATUS_SUCCESS) 289 goto err_peer_create; 290 291 status = wlan_objmgr_register_vdev_destroy_handler( 292 WLAN_UMAC_COMP_CRYPTO, 293 wlan_crypto_vdev_obj_destroy_handler, NULL); 294 if (status != QDF_STATUS_SUCCESS) 295 goto err_vdev_delete; 296 297 status = wlan_objmgr_register_peer_destroy_handler( 298 WLAN_UMAC_COMP_CRYPTO, 299 wlan_crypto_peer_obj_destroy_handler, NULL); 300 if (status != QDF_STATUS_SUCCESS) 301 goto err_peer_delete; 302 303 goto register_success; 304 err_peer_delete: 305 wlan_objmgr_unregister_vdev_destroy_handler(WLAN_UMAC_COMP_CRYPTO, 306 wlan_crypto_vdev_obj_destroy_handler, NULL); 307 err_vdev_delete: 308 wlan_objmgr_unregister_peer_create_handler(WLAN_UMAC_COMP_CRYPTO, 309 wlan_crypto_peer_obj_create_handler, NULL); 310 err_peer_create: 311 wlan_objmgr_unregister_vdev_create_handler(WLAN_UMAC_COMP_CRYPTO, 312 wlan_crypto_vdev_obj_create_handler, NULL); 313 err_vdev_create: 314 wlan_objmgr_unregister_pdev_create_handler(WLAN_UMAC_COMP_CRYPTO, 315 wlan_crypto_pdev_obj_create_handler, NULL); 316 register_success: 317 return status; 318 } 319 320 /** 321 * __wlan_crypto_deinit - Deinit the crypto service with object manager 322 * Called from crypto context. 323 * 324 * Return: QDF_STATUS_SUCCESS - in case of success 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