Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 /*
0003  * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
0004  * All rights reserved.
0005  *
0006  * Purpose: Implement functions for 802.11i Key management
0007  *
0008  * Author: Jerry Chen
0009  *
0010  * Date: May 29, 2003
0011  *
0012  */
0013 
0014 #include "key.h"
0015 #include "mac.h"
0016 
0017 static int vnt_set_keymode(struct ieee80211_hw *hw, u8 *mac_addr,
0018                struct ieee80211_key_conf *key, u32 key_type,
0019                u32 mode, bool onfly_latch)
0020 {
0021     struct vnt_private *priv = hw->priv;
0022     u8 broadcast[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
0023     u16 key_mode = 0;
0024     u32 entry = 0;
0025     u8 *bssid;
0026     u8 key_inx = key->keyidx;
0027     u8 i;
0028 
0029     if (mac_addr)
0030         bssid = mac_addr;
0031     else
0032         bssid = &broadcast[0];
0033 
0034     if (key_type != VNT_KEY_DEFAULTKEY) {
0035         for (i = 0; i < (MAX_KEY_TABLE - 1); i++) {
0036             if (!test_bit(i, &priv->key_entry_inuse)) {
0037                 set_bit(i, &priv->key_entry_inuse);
0038 
0039                 key->hw_key_idx = i;
0040                 entry = key->hw_key_idx;
0041                 break;
0042             }
0043         }
0044     }
0045 
0046     switch (key_type) {
0047     case VNT_KEY_DEFAULTKEY:
0048         /* default key last entry */
0049         entry = MAX_KEY_TABLE - 1;
0050         key->hw_key_idx = entry;
0051         fallthrough;
0052     case VNT_KEY_ALLGROUP:
0053         key_mode |= VNT_KEY_ALLGROUP;
0054         if (onfly_latch)
0055             key_mode |= VNT_KEY_ONFLY_ALL;
0056         fallthrough;
0057     case VNT_KEY_GROUP_ADDRESS:
0058         key_mode |= mode;
0059         fallthrough;
0060     case VNT_KEY_GROUP:
0061         key_mode |= (mode << 4);
0062         key_mode |= VNT_KEY_GROUP;
0063         break;
0064     case  VNT_KEY_PAIRWISE:
0065         key_mode |= mode;
0066         key_inx = 4;
0067         break;
0068     default:
0069         return -EINVAL;
0070     }
0071 
0072     if (onfly_latch)
0073         key_mode |= VNT_KEY_ONFLY;
0074 
0075     if (mode == KEY_CTL_WEP) {
0076         if (key->keylen == WLAN_KEY_LEN_WEP40)
0077             key->key[15] &= 0x7f;
0078         if (key->keylen == WLAN_KEY_LEN_WEP104)
0079             key->key[15] |= 0x80;
0080     }
0081 
0082     MACvSetKeyEntry(priv, key_mode, entry, key_inx,
0083             bssid, (u32 *)key->key, priv->local_id);
0084 
0085     return 0;
0086 }
0087 
0088 int vnt_set_keys(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
0089          struct ieee80211_vif *vif, struct ieee80211_key_conf *key)
0090 {
0091     struct ieee80211_bss_conf *conf = &vif->bss_conf;
0092     struct vnt_private *priv = hw->priv;
0093     u8 *mac_addr = NULL;
0094     u8 key_dec_mode = 0;
0095     int ret = 0;
0096     u32 u;
0097 
0098     if (sta)
0099         mac_addr = &sta->addr[0];
0100 
0101     switch (key->cipher) {
0102     case 0:
0103         for (u = 0 ; u < MAX_KEY_TABLE; u++)
0104             MACvDisableKeyEntry(priv, u);
0105         return ret;
0106 
0107     case WLAN_CIPHER_SUITE_WEP40:
0108     case WLAN_CIPHER_SUITE_WEP104:
0109         for (u = 0; u < MAX_KEY_TABLE; u++)
0110             MACvDisableKeyEntry(priv, u);
0111 
0112         vnt_set_keymode(hw, mac_addr,
0113                 key, VNT_KEY_DEFAULTKEY, KEY_CTL_WEP, true);
0114 
0115         key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
0116 
0117         return ret;
0118     case WLAN_CIPHER_SUITE_TKIP:
0119         key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
0120         key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
0121 
0122         key_dec_mode = KEY_CTL_TKIP;
0123 
0124         break;
0125     case WLAN_CIPHER_SUITE_CCMP:
0126         key_dec_mode = KEY_CTL_CCMP;
0127 
0128         key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
0129     }
0130 
0131     if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) {
0132         vnt_set_keymode(hw, mac_addr,
0133                 key, VNT_KEY_PAIRWISE, key_dec_mode, true);
0134     } else {
0135         vnt_set_keymode(hw, mac_addr,
0136                 key, VNT_KEY_DEFAULTKEY, key_dec_mode, true);
0137 
0138         vnt_set_keymode(hw, (u8 *)conf->bssid,
0139                 key, VNT_KEY_GROUP_ADDRESS, key_dec_mode, true);
0140     }
0141 
0142     return 0;
0143 }