1 /* 2 * Copyright (c) 2017-2019 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 } 199 200 static QDF_STATUS wlan_crypto_vdev_obj_destroy_handler( 201 struct wlan_objmgr_vdev *vdev, 202 void *arg){ 203 struct wlan_crypto_comp_priv *crypto_priv; 204 205 if (!vdev) { 206 crypto_err("Vdev NULL"); 207 return QDF_STATUS_E_INVAL; 208 } 209 210 crypto_priv = (struct wlan_crypto_comp_priv *) 211 wlan_get_vdev_crypto_obj(vdev); 212 213 if (!crypto_priv) { 214 crypto_err("crypto_priv NULL"); 215 return QDF_STATUS_E_INVAL; 216 } 217 218 wlan_objmgr_vdev_component_obj_detach(vdev, 219 WLAN_UMAC_COMP_CRYPTO, 220 (void *)crypto_priv); 221 222 wlan_crypto_pmksa_flush(&crypto_priv->crypto_params); 223 wlan_crypto_free_key(crypto_priv); 224 qdf_mem_free(crypto_priv); 225 226 return QDF_STATUS_SUCCESS; 227 } 228 229 static QDF_STATUS wlan_crypto_peer_obj_destroy_handler( 230 struct wlan_objmgr_peer *peer, 231 void *arg){ 232 struct wlan_crypto_comp_priv *crypto_priv; 233 234 if (!peer) { 235 crypto_err("Peer NULL"); 236 return QDF_STATUS_E_INVAL; 237 } 238 crypto_priv = (struct wlan_crypto_comp_priv *) 239 wlan_get_peer_crypto_obj(peer); 240 if (!crypto_priv) { 241 crypto_err("crypto_priv NULL"); 242 return QDF_STATUS_E_INVAL; 243 } 244 245 wlan_objmgr_peer_component_obj_detach(peer, 246 WLAN_UMAC_COMP_CRYPTO, 247 (void *)crypto_priv); 248 wlan_crypto_free_key(crypto_priv); 249 qdf_mem_free(crypto_priv); 250 251 return QDF_STATUS_SUCCESS; 252 } 253 /** 254 * __wlan_crypto_init - Init the crypto service with object manager 255 * Called from crypto init context. 256 * 257 * Return: QDF_STATUS_SUCCESS - in case of success 258 */ 259 QDF_STATUS __wlan_crypto_init(void) 260 { 261 QDF_STATUS status = QDF_STATUS_SUCCESS; 262 263 status = wlan_objmgr_register_vdev_create_handler( 264 WLAN_UMAC_COMP_CRYPTO, 265 wlan_crypto_vdev_obj_create_handler, NULL); 266 if (status != QDF_STATUS_SUCCESS) 267 return status; 268 269 status = wlan_objmgr_register_peer_create_handler( 270 WLAN_UMAC_COMP_CRYPTO, 271 wlan_crypto_peer_obj_create_handler, NULL); 272 if (status != QDF_STATUS_SUCCESS) 273 goto err_peer_create; 274 275 status = wlan_objmgr_register_vdev_destroy_handler( 276 WLAN_UMAC_COMP_CRYPTO, 277 wlan_crypto_vdev_obj_destroy_handler, NULL); 278 if (status != QDF_STATUS_SUCCESS) 279 goto err_vdev_delete; 280 281 status = wlan_objmgr_register_peer_destroy_handler( 282 WLAN_UMAC_COMP_CRYPTO, 283 wlan_crypto_peer_obj_destroy_handler, NULL); 284 if (status != QDF_STATUS_SUCCESS) 285 goto err_peer_delete; 286 287 goto register_success; 288 err_peer_delete: 289 wlan_objmgr_unregister_vdev_destroy_handler(WLAN_UMAC_COMP_CRYPTO, 290 wlan_crypto_vdev_obj_destroy_handler, NULL); 291 err_vdev_delete: 292 wlan_objmgr_unregister_peer_create_handler(WLAN_UMAC_COMP_CRYPTO, 293 wlan_crypto_peer_obj_create_handler, NULL); 294 err_peer_create: 295 wlan_objmgr_unregister_vdev_create_handler(WLAN_UMAC_COMP_CRYPTO, 296 wlan_crypto_vdev_obj_create_handler, NULL); 297 298 register_success: 299 return status; 300 } 301 302 /** 303 * __wlan_crypto_deinit - Deinit the crypto service with object manager 304 * Called from crypto context. 305 * 306 * Return: QDF_STATUS_SUCCESS - in case of success 307 */ 308 QDF_STATUS __wlan_crypto_deinit(void) 309 { 310 311 if (wlan_objmgr_unregister_vdev_create_handler(WLAN_UMAC_COMP_CRYPTO, 312 wlan_crypto_vdev_obj_create_handler, NULL) 313 != QDF_STATUS_SUCCESS) { 314 return QDF_STATUS_E_FAILURE; 315 } 316 317 if (wlan_objmgr_unregister_peer_create_handler(WLAN_UMAC_COMP_CRYPTO, 318 wlan_crypto_peer_obj_create_handler, NULL) 319 != QDF_STATUS_SUCCESS) { 320 return QDF_STATUS_E_FAILURE; 321 } 322 323 if (wlan_objmgr_unregister_vdev_destroy_handler(WLAN_UMAC_COMP_CRYPTO, 324 wlan_crypto_vdev_obj_destroy_handler, NULL) 325 != QDF_STATUS_SUCCESS) { 326 return QDF_STATUS_E_FAILURE; 327 } 328 329 if (wlan_objmgr_unregister_peer_destroy_handler(WLAN_UMAC_COMP_CRYPTO, 330 wlan_crypto_peer_obj_destroy_handler, NULL) 331 != QDF_STATUS_SUCCESS) { 332 return QDF_STATUS_E_FAILURE; 333 } 334 335 return QDF_STATUS_SUCCESS; 336 } 337