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 management |
7 | * |
8 | * Author: Jerry Chen |
9 | * |
10 | * Date: May 29, 2003 |
11 | * |
12 | */ |
13 | |
14 | #include "key.h" |
15 | #include "mac.h" |
16 | |
17 | static int vnt_set_keymode(struct ieee80211_hw *hw, u8 *mac_addr, |
18 | struct ieee80211_key_conf *key, u32 key_type, |
19 | u32 mode, bool onfly_latch) |
20 | { |
21 | struct vnt_private *priv = hw->priv; |
22 | u8 broadcast[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; |
23 | u16 key_mode = 0; |
24 | u32 entry = 0; |
25 | u8 *bssid; |
26 | u8 key_inx = key->keyidx; |
27 | u8 i; |
28 | |
29 | if (mac_addr) |
30 | bssid = mac_addr; |
31 | else |
32 | bssid = &broadcast[0]; |
33 | |
34 | if (key_type != VNT_KEY_DEFAULTKEY) { |
35 | for (i = 0; i < (MAX_KEY_TABLE - 1); i++) { |
36 | if (!test_bit(i, &priv->key_entry_inuse)) { |
37 | set_bit(nr: i, addr: &priv->key_entry_inuse); |
38 | |
39 | key->hw_key_idx = i; |
40 | entry = key->hw_key_idx; |
41 | break; |
42 | } |
43 | } |
44 | } |
45 | |
46 | switch (key_type) { |
47 | case VNT_KEY_DEFAULTKEY: |
48 | /* default key last entry */ |
49 | entry = MAX_KEY_TABLE - 1; |
50 | key->hw_key_idx = entry; |
51 | fallthrough; |
52 | case VNT_KEY_ALLGROUP: |
53 | key_mode |= VNT_KEY_ALLGROUP; |
54 | if (onfly_latch) |
55 | key_mode |= VNT_KEY_ONFLY_ALL; |
56 | fallthrough; |
57 | case VNT_KEY_GROUP_ADDRESS: |
58 | key_mode |= mode; |
59 | fallthrough; |
60 | case VNT_KEY_GROUP: |
61 | key_mode |= (mode << 4); |
62 | key_mode |= VNT_KEY_GROUP; |
63 | break; |
64 | case VNT_KEY_PAIRWISE: |
65 | key_mode |= mode; |
66 | key_inx = 4; |
67 | break; |
68 | default: |
69 | return -EINVAL; |
70 | } |
71 | |
72 | if (onfly_latch) |
73 | key_mode |= VNT_KEY_ONFLY; |
74 | |
75 | if (mode == KEY_CTL_WEP) { |
76 | if (key->keylen == WLAN_KEY_LEN_WEP40) |
77 | key->key[15] &= 0x7f; |
78 | if (key->keylen == WLAN_KEY_LEN_WEP104) |
79 | key->key[15] |= 0x80; |
80 | } |
81 | |
82 | MACvSetKeyEntry(priv, wKeyCtl: key_mode, uEntryIdx: entry, uKeyIdx: key_inx, |
83 | pbyAddr: bssid, pdwKey: (u32 *)key->key, local_id: priv->local_id); |
84 | |
85 | return 0; |
86 | } |
87 | |
88 | int vnt_set_keys(struct ieee80211_hw *hw, struct ieee80211_sta *sta, |
89 | struct ieee80211_vif *vif, struct ieee80211_key_conf *key) |
90 | { |
91 | struct ieee80211_bss_conf *conf = &vif->bss_conf; |
92 | struct vnt_private *priv = hw->priv; |
93 | u8 *mac_addr = NULL; |
94 | u8 key_dec_mode = 0; |
95 | int ret = 0; |
96 | u32 u; |
97 | |
98 | if (sta) |
99 | mac_addr = &sta->addr[0]; |
100 | |
101 | switch (key->cipher) { |
102 | case 0: |
103 | for (u = 0 ; u < MAX_KEY_TABLE; u++) |
104 | MACvDisableKeyEntry(priv, uEntryIdx: u); |
105 | return ret; |
106 | |
107 | case WLAN_CIPHER_SUITE_WEP40: |
108 | case WLAN_CIPHER_SUITE_WEP104: |
109 | for (u = 0; u < MAX_KEY_TABLE; u++) |
110 | MACvDisableKeyEntry(priv, uEntryIdx: u); |
111 | |
112 | vnt_set_keymode(hw, mac_addr, |
113 | key, VNT_KEY_DEFAULTKEY, KEY_CTL_WEP, onfly_latch: true); |
114 | |
115 | key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; |
116 | |
117 | return ret; |
118 | case WLAN_CIPHER_SUITE_TKIP: |
119 | key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; |
120 | key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; |
121 | |
122 | key_dec_mode = KEY_CTL_TKIP; |
123 | |
124 | break; |
125 | case WLAN_CIPHER_SUITE_CCMP: |
126 | key_dec_mode = KEY_CTL_CCMP; |
127 | |
128 | key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; |
129 | } |
130 | |
131 | if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) { |
132 | vnt_set_keymode(hw, mac_addr, |
133 | key, VNT_KEY_PAIRWISE, mode: key_dec_mode, onfly_latch: true); |
134 | } else { |
135 | vnt_set_keymode(hw, mac_addr, |
136 | key, VNT_KEY_DEFAULTKEY, mode: key_dec_mode, onfly_latch: true); |
137 | |
138 | vnt_set_keymode(hw, mac_addr: (u8 *)conf->bssid, |
139 | key, VNT_KEY_GROUP_ADDRESS, mode: key_dec_mode, onfly_latch: true); |
140 | } |
141 | |
142 | return 0; |
143 | } |
144 | |