143 lines · c
1// SPDX-License-Identifier: GPL-2.0+2/*3 * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.4 * All rights reserved.5 *6 * Purpose: Implement functions for 802.11i Key management7 *8 * Author: Jerry Chen9 *10 * Date: May 29, 200311 *12 * Functions:13 *14 * Revision History:15 *16 */17 18#include "mac.h"19#include "key.h"20#include "usbpipe.h"21 22int vnt_key_init_table(struct vnt_private *priv)23{24 u8 i;25 u8 data[MAX_KEY_TABLE];26 27 for (i = 0; i < MAX_KEY_TABLE; i++)28 data[i] = i;29 30 return vnt_control_out(priv, MESSAGE_TYPE_CLRKEYENTRY,31 0, 0, ARRAY_SIZE(data), data);32}33 34static int vnt_set_keymode(struct ieee80211_hw *hw, u8 *mac_addr,35 struct ieee80211_key_conf *key, u32 key_type,36 u32 mode)37{38 struct vnt_private *priv = hw->priv;39 u8 broadcast[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};40 u16 key_mode = 0;41 u32 entry = 0;42 u8 *bssid;43 u8 key_inx = key->keyidx;44 u8 i;45 46 if (mac_addr)47 bssid = mac_addr;48 else49 bssid = &broadcast[0];50 51 if (key_type != VNT_KEY_DEFAULTKEY) {52 for (i = 0; i < (MAX_KEY_TABLE - 1); i++) {53 if (!test_bit(i, &priv->key_entry_inuse)) {54 set_bit(i, &priv->key_entry_inuse);55 56 key->hw_key_idx = i;57 entry = key->hw_key_idx;58 break;59 }60 }61 }62 63 switch (key_type) {64 case VNT_KEY_DEFAULTKEY:65 /* default key last entry */66 entry = MAX_KEY_TABLE - 1;67 key->hw_key_idx = entry;68 fallthrough;69 case VNT_KEY_GROUP_ADDRESS:70 key_mode = mode | (mode << 4);71 break;72 case VNT_KEY_GROUP:73 key_mode = mode << 4;74 break;75 case VNT_KEY_PAIRWISE:76 key_mode |= mode;77 key_inx = 4;78 break;79 default:80 return -EINVAL;81 }82 83 key_mode |= key_type;84 85 if (mode == KEY_CTL_WEP) {86 if (key->keylen == WLAN_KEY_LEN_WEP40)87 key->key[15] &= 0x7f;88 if (key->keylen == WLAN_KEY_LEN_WEP104)89 key->key[15] |= 0x80;90 }91 92 return vnt_mac_set_keyentry(priv, key_mode, entry,93 key_inx, bssid, key->key);94}95 96int vnt_set_keys(struct ieee80211_hw *hw, struct ieee80211_sta *sta,97 struct ieee80211_vif *vif, struct ieee80211_key_conf *key)98{99 struct vnt_private *priv = hw->priv;100 u8 *mac_addr = NULL;101 u8 key_dec_mode = 0;102 103 if (sta)104 mac_addr = &sta->addr[0];105 106 switch (key->cipher) {107 case WLAN_CIPHER_SUITE_WEP40:108 case WLAN_CIPHER_SUITE_WEP104:109 vnt_set_keymode(hw, mac_addr, key, VNT_KEY_DEFAULTKEY,110 KEY_CTL_WEP);111 112 key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;113 114 return vnt_set_keymode(hw, mac_addr, key, VNT_KEY_DEFAULTKEY,115 KEY_CTL_WEP);116 117 case WLAN_CIPHER_SUITE_TKIP:118 key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;119 key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;120 121 key_dec_mode = KEY_CTL_TKIP;122 123 break;124 case WLAN_CIPHER_SUITE_CCMP:125 if (priv->local_id <= MAC_REVISION_A1)126 return -EOPNOTSUPP;127 128 key_dec_mode = KEY_CTL_CCMP;129 130 key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;131 break;132 default:133 return -EOPNOTSUPP;134 }135 136 if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE)137 return vnt_set_keymode(hw, mac_addr, key, VNT_KEY_PAIRWISE,138 key_dec_mode);139 140 return vnt_set_keymode(hw, mac_addr, key,141 VNT_KEY_GROUP_ADDRESS, key_dec_mode);142}143