1 /* 2 * Copyright (c) 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: wlan_nl_to_crypto_params.c 21 * 22 * Conversion of NL param type to Crypto param type APIs implementation 23 * 24 */ 25 26 #include <linux/module.h> 27 #include <linux/kernel.h> 28 #include <linux/version.h> 29 #include <linux/netdevice.h> 30 #include <net/netlink.h> 31 #include <net/cfg80211.h> 32 33 #include <qdf_types.h> 34 #include "wlan_objmgr_vdev_obj.h" 35 #include <qdf_module.h> 36 37 #include "wlan_nl_to_crypto_params.h" 38 #include "wlan_crypto_global_def.h" 39 40 /** 41 * struct osif_akm_crypto_mapping - mapping akm type received from 42 * NL to internal crypto type 43 * @akm_suite: NL akm type 44 * @akm_type_crypto: akm crypto type 45 * 46 * mapping akm type received from NL to internal crypto type 47 */ 48 struct osif_akm_type_crypto_mapping { 49 u32 akm_suite; 50 wlan_crypto_key_mgmt akm_type_crypto; 51 }; 52 53 /** 54 * struct osif_cipher_crypto_mapping - mapping cipher type received from NL 55 * to internal crypto cipher type 56 * @cipher_suite: NL cipher type 57 * @cipher_crypto: cipher crypto type 58 * 59 * mapping cipher type received from NL to internal crypto cipher type 60 */ 61 struct osif_cipher_crypto_mapping { 62 u32 cipher_suite; 63 wlan_crypto_cipher_type cipher_crypto; 64 }; 65 66 /** 67 * mapping table for auth type received from NL and cryto auth type 68 */ 69 static const wlan_crypto_auth_mode 70 osif_auth_type_crypto_mapping[] = { 71 [NL80211_AUTHTYPE_AUTOMATIC] = WLAN_CRYPTO_AUTH_AUTO, 72 [NL80211_AUTHTYPE_OPEN_SYSTEM] = WLAN_CRYPTO_AUTH_OPEN, 73 [NL80211_AUTHTYPE_FT] = WLAN_CRYPTO_AUTH_OPEN, 74 [NL80211_AUTHTYPE_SHARED_KEY] = WLAN_CRYPTO_AUTH_SHARED, 75 [NL80211_AUTHTYPE_NETWORK_EAP] = WLAN_CRYPTO_AUTH_8021X, 76 #if defined(WLAN_FEATURE_FILS_SK) && \ 77 (defined(CFG80211_FILS_SK_OFFLOAD_SUPPORT) || \ 78 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0))) 79 [NL80211_AUTHTYPE_FILS_SK] = WLAN_CRYPTO_AUTH_FILS_SK, 80 #endif 81 [NL80211_AUTHTYPE_SAE] = WLAN_CRYPTO_AUTH_SAE, 82 }; 83 84 /* mapping table for akm type received from NL and cryto akm type */ 85 static const struct osif_akm_type_crypto_mapping 86 osif_akm_type_crypto_mapping[] = { 87 { 88 .akm_suite = WLAN_AKM_SUITE_8021X, 89 .akm_type_crypto = WLAN_CRYPTO_KEY_MGMT_IEEE8021X, 90 }, 91 { 92 .akm_suite = WLAN_AKM_SUITE_PSK, 93 .akm_type_crypto = WLAN_CRYPTO_KEY_MGMT_PSK, 94 }, 95 { 96 .akm_suite = WLAN_AKM_SUITE_8021X_SHA256, 97 .akm_type_crypto = WLAN_CRYPTO_KEY_MGMT_IEEE8021X_SHA256, 98 }, 99 { 100 .akm_suite = WLAN_AKM_SUITE_PSK_SHA256, 101 .akm_type_crypto = WLAN_CRYPTO_KEY_MGMT_PSK_SHA256, 102 }, 103 { 104 .akm_suite = WLAN_AKM_SUITE_SAE, 105 .akm_type_crypto = WLAN_CRYPTO_KEY_MGMT_SAE, 106 }, 107 { 108 .akm_suite = WLAN_AKM_SUITE_FT_OVER_SAE, 109 .akm_type_crypto = WLAN_CRYPTO_KEY_MGMT_FT_SAE, 110 }, 111 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)) || \ 112 defined(FEATURE_WLAN_FT_IEEE8021X) 113 { 114 .akm_suite = WLAN_AKM_SUITE_FT_8021X, 115 .akm_type_crypto = WLAN_CRYPTO_KEY_MGMT_FT_IEEE8021X, 116 }, 117 #endif 118 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)) || \ 119 defined(FEATURE_WLAN_FT_PSK) 120 { 121 .akm_suite = WLAN_AKM_SUITE_FT_PSK, 122 .akm_type_crypto = WLAN_CRYPTO_KEY_MGMT_FT_PSK, 123 }, 124 #endif 125 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)) || \ 126 defined(FEATURE_WLAN_IEEE8021X_SUITE_B) 127 { 128 .akm_suite = WLAN_AKM_SUITE_8021X_SUITE_B, 129 .akm_type_crypto = WLAN_CRYPTO_KEY_MGMT_IEEE8021X_SUITE_B, 130 }, 131 { 132 .akm_suite = WLAN_AKM_SUITE_8021X_SUITE_B_192, 133 .akm_type_crypto = WLAN_CRYPTO_KEY_MGMT_IEEE8021X_SUITE_B_192, 134 }, 135 #endif 136 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0)) || \ 137 defined(FEATURE_WLAN_FILS) 138 { 139 .akm_suite = WLAN_AKM_SUITE_FILS_SHA256, 140 .akm_type_crypto = WLAN_CRYPTO_KEY_MGMT_FILS_SHA256, 141 }, 142 { 143 .akm_suite = WLAN_AKM_SUITE_FILS_SHA384, 144 .akm_type_crypto = WLAN_CRYPTO_KEY_MGMT_FILS_SHA384, 145 }, 146 { 147 .akm_suite = WLAN_AKM_SUITE_FT_FILS_SHA256, 148 .akm_type_crypto = WLAN_CRYPTO_KEY_MGMT_FT_FILS_SHA256, 149 }, 150 { 151 .akm_suite = WLAN_AKM_SUITE_FT_FILS_SHA384, 152 .akm_type_crypto = WLAN_CRYPTO_KEY_MGMT_FT_FILS_SHA384, 153 }, 154 #endif 155 }; 156 157 /* mapping table for cipher type received from NL and cryto cipher type */ 158 static const struct osif_cipher_crypto_mapping 159 osif_cipher_crypto_mapping[] = { 160 { 161 .cipher_suite = IW_AUTH_CIPHER_NONE, 162 .cipher_crypto = WLAN_CRYPTO_CIPHER_NONE, 163 }, 164 { 165 .cipher_suite = WLAN_CIPHER_SUITE_WEP40, 166 .cipher_crypto = WLAN_CRYPTO_CIPHER_WEP_40, 167 }, 168 { 169 .cipher_suite = WLAN_CIPHER_SUITE_TKIP, 170 .cipher_crypto = WLAN_CRYPTO_CIPHER_TKIP, 171 }, 172 { 173 .cipher_suite = WLAN_CIPHER_SUITE_CCMP, 174 .cipher_crypto = WLAN_CRYPTO_CIPHER_AES_CCM, 175 }, 176 { 177 .cipher_suite = WLAN_CIPHER_SUITE_WEP104, 178 .cipher_crypto = WLAN_CRYPTO_CIPHER_WEP_104, 179 }, 180 { 181 .cipher_suite = WLAN_CIPHER_SUITE_GCMP, 182 .cipher_crypto = WLAN_CRYPTO_CIPHER_AES_GCM, 183 }, 184 { 185 .cipher_suite = WLAN_CIPHER_SUITE_GCMP_256, 186 .cipher_crypto = WLAN_CRYPTO_CIPHER_AES_GCM_256, 187 }, 188 { 189 .cipher_suite = WLAN_CIPHER_SUITE_CCMP_256, 190 .cipher_crypto = WLAN_CRYPTO_CIPHER_AES_CCM_256, 191 }, 192 { 193 .cipher_suite = WLAN_CIPHER_SUITE_AES_CMAC, 194 .cipher_crypto = WLAN_CRYPTO_CIPHER_AES_CMAC, 195 }, 196 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) 197 { 198 .cipher_suite = WLAN_CIPHER_SUITE_BIP_GMAC_128, 199 .cipher_crypto = WLAN_CRYPTO_CIPHER_AES_GMAC, 200 }, 201 { 202 .cipher_suite = WLAN_CIPHER_SUITE_BIP_GMAC_256, 203 .cipher_crypto = WLAN_CRYPTO_CIPHER_AES_GMAC_256, 204 }, 205 { 206 .cipher_suite = WLAN_CIPHER_SUITE_BIP_CMAC_256, 207 .cipher_crypto = WLAN_CRYPTO_CIPHER_AES_CMAC_256, 208 }, 209 #endif 210 #ifdef FEATURE_WLAN_WAPI 211 { 212 .cipher_suite = WLAN_CIPHER_SUITE_SMS4, 213 .cipher_crypto = WLAN_CRYPTO_CIPHER_WAPI_SMS4, 214 }, 215 #endif 216 }; 217 218 int osif_nl_to_crypto_auth_type(enum nl80211_auth_type auth_type) 219 { 220 wlan_crypto_auth_mode crypto_auth_type = WLAN_CRYPTO_AUTH_NONE; 221 222 if (auth_type < NL80211_AUTHTYPE_OPEN_SYSTEM || 223 auth_type >= QDF_ARRAY_SIZE(osif_auth_type_crypto_mapping)) { 224 QDF_TRACE_ERROR(QDF_MODULE_ID_OS_IF, "Unknown type: %d", 225 auth_type); 226 return -EINVAL; 227 } 228 QDF_TRACE_DEBUG(QDF_MODULE_ID_OS_IF, "Auth type, NL: %d, crypto: %d", 229 auth_type, osif_auth_type_crypto_mapping[auth_type]); 230 231 return crypto_auth_type; 232 } 233 234 int osif_nl_to_crypto_akm_type(u32 key_mgmt) 235 { 236 uint8_t index; 237 wlan_crypto_key_mgmt crypto_akm_type = WLAN_CRYPTO_KEY_MGMT_NONE; 238 bool akm_type_crypto_exist = false; 239 240 for (index = 0; index < QDF_ARRAY_SIZE(osif_akm_type_crypto_mapping); 241 index++) { 242 if (osif_akm_type_crypto_mapping[index].akm_suite == key_mgmt) { 243 crypto_akm_type = osif_akm_type_crypto_mapping[index]. 244 akm_type_crypto; 245 akm_type_crypto_exist = true; 246 break; 247 } 248 } 249 if (!akm_type_crypto_exist) { 250 QDF_TRACE_ERROR(QDF_MODULE_ID_OS_IF, "Unknown type: %d", 251 key_mgmt); 252 return -EINVAL; 253 } 254 QDF_TRACE_DEBUG(QDF_MODULE_ID_OS_IF, "Akm suite, NL: %d, crypto: %d", 255 key_mgmt, crypto_akm_type); 256 257 return crypto_akm_type; 258 } 259 260 int osif_nl_to_crypto_cipher_type(u32 cipher) 261 { 262 uint8_t index; 263 bool cipher_crypto_exist = false; 264 wlan_crypto_cipher_type crypto_cipher_type = WLAN_CRYPTO_CIPHER_NONE; 265 266 for (index = 0; index < QDF_ARRAY_SIZE(osif_auth_type_crypto_mapping); 267 index++) { 268 if (osif_cipher_crypto_mapping[index].cipher_suite == cipher) { 269 crypto_cipher_type = osif_cipher_crypto_mapping[index]. 270 cipher_crypto; 271 cipher_crypto_exist = true; 272 break; 273 } 274 } 275 if (!cipher_crypto_exist) { 276 QDF_TRACE_ERROR(QDF_MODULE_ID_OS_IF, "Unknown type: %d", 277 cipher); 278 return -EINVAL; 279 } 280 QDF_TRACE_DEBUG(QDF_MODULE_ID_OS_IF, "Cipher suite, NL: %d, crypto: %d", 281 cipher, crypto_cipher_type); 282 283 return crypto_cipher_type; 284 } 285