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  * Functions:
0013  *
0014  * Revision History:
0015  *
0016  */
0017 
0018 #include "mac.h"
0019 #include "key.h"
0020 #include "usbpipe.h"
0021 
0022 int vnt_key_init_table(struct vnt_private *priv)
0023 {
0024     u8 i;
0025     u8 data[MAX_KEY_TABLE];
0026 
0027     for (i = 0; i < MAX_KEY_TABLE; i++)
0028         data[i] = i;
0029 
0030     return vnt_control_out(priv, MESSAGE_TYPE_CLRKEYENTRY,
0031             0, 0, ARRAY_SIZE(data), data);
0032 }
0033 
0034 static int vnt_set_keymode(struct ieee80211_hw *hw, u8 *mac_addr,
0035                struct ieee80211_key_conf *key, u32 key_type,
0036                u32 mode)
0037 {
0038     struct vnt_private *priv = hw->priv;
0039     u8 broadcast[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
0040     u16 key_mode = 0;
0041     u32 entry = 0;
0042     u8 *bssid;
0043     u8 key_inx = key->keyidx;
0044     u8 i;
0045 
0046     if (mac_addr)
0047         bssid = mac_addr;
0048     else
0049         bssid = &broadcast[0];
0050 
0051     if (key_type != VNT_KEY_DEFAULTKEY) {
0052         for (i = 0; i < (MAX_KEY_TABLE - 1); i++) {
0053             if (!test_bit(i, &priv->key_entry_inuse)) {
0054                 set_bit(i, &priv->key_entry_inuse);
0055 
0056                 key->hw_key_idx = i;
0057                 entry = key->hw_key_idx;
0058                 break;
0059             }
0060         }
0061     }
0062 
0063     switch (key_type) {
0064     case VNT_KEY_DEFAULTKEY:
0065         /* default key last entry */
0066         entry = MAX_KEY_TABLE - 1;
0067         key->hw_key_idx = entry;
0068         fallthrough;
0069     case VNT_KEY_GROUP_ADDRESS:
0070         key_mode = mode | (mode << 4);
0071         break;
0072     case VNT_KEY_GROUP:
0073         key_mode = mode << 4;
0074         break;
0075     case  VNT_KEY_PAIRWISE:
0076         key_mode |= mode;
0077         key_inx = 4;
0078         break;
0079     default:
0080         return -EINVAL;
0081     }
0082 
0083     key_mode |= key_type;
0084 
0085     if (mode == KEY_CTL_WEP) {
0086         if (key->keylen == WLAN_KEY_LEN_WEP40)
0087             key->key[15] &= 0x7f;
0088         if (key->keylen == WLAN_KEY_LEN_WEP104)
0089             key->key[15] |= 0x80;
0090     }
0091 
0092     return vnt_mac_set_keyentry(priv, key_mode, entry,
0093                     key_inx, bssid, key->key);
0094 }
0095 
0096 int vnt_set_keys(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
0097          struct ieee80211_vif *vif, struct ieee80211_key_conf *key)
0098 {
0099     struct vnt_private *priv = hw->priv;
0100     u8 *mac_addr = NULL;
0101     u8 key_dec_mode = 0;
0102 
0103     if (sta)
0104         mac_addr = &sta->addr[0];
0105 
0106     switch (key->cipher) {
0107     case WLAN_CIPHER_SUITE_WEP40:
0108     case WLAN_CIPHER_SUITE_WEP104:
0109         vnt_set_keymode(hw, mac_addr, key, VNT_KEY_DEFAULTKEY,
0110                 KEY_CTL_WEP);
0111 
0112         key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
0113 
0114         return vnt_set_keymode(hw, mac_addr, key, VNT_KEY_DEFAULTKEY,
0115                        KEY_CTL_WEP);
0116 
0117     case WLAN_CIPHER_SUITE_TKIP:
0118         key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
0119         key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
0120 
0121         key_dec_mode = KEY_CTL_TKIP;
0122 
0123         break;
0124     case WLAN_CIPHER_SUITE_CCMP:
0125         if (priv->local_id <= MAC_REVISION_A1)
0126             return -EOPNOTSUPP;
0127 
0128         key_dec_mode = KEY_CTL_CCMP;
0129 
0130         key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
0131         break;
0132     default:
0133         return -EOPNOTSUPP;
0134     }
0135 
0136     if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE)
0137         return vnt_set_keymode(hw, mac_addr, key, VNT_KEY_PAIRWISE,
0138                        key_dec_mode);
0139 
0140     return vnt_set_keymode(hw, mac_addr, key,
0141                 VNT_KEY_GROUP_ADDRESS, key_dec_mode);
0142 }