.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * Software WEP encryption implementation |
---|
3 | 4 | * Copyright 2002, Jouni Malinen <jkmaline@cc.hut.fi> |
---|
4 | 5 | * Copyright 2003, Instant802 Networks, Inc. |
---|
5 | | - * |
---|
6 | | - * This program is free software; you can redistribute it and/or modify |
---|
7 | | - * it under the terms of the GNU General Public License version 2 as |
---|
8 | | - * published by the Free Software Foundation. |
---|
9 | 6 | */ |
---|
10 | 7 | |
---|
11 | 8 | #include <linux/netdevice.h> |
---|
.. | .. |
---|
25 | 22 | #include "wep.h" |
---|
26 | 23 | |
---|
27 | 24 | |
---|
28 | | -int ieee80211_wep_init(struct ieee80211_local *local) |
---|
| 25 | +void ieee80211_wep_init(struct ieee80211_local *local) |
---|
29 | 26 | { |
---|
30 | 27 | /* start WEP IV from a random value */ |
---|
31 | 28 | get_random_bytes(&local->wep_iv, IEEE80211_WEP_IV_LEN); |
---|
32 | | - |
---|
33 | | - local->wep_tx_tfm = crypto_alloc_cipher("arc4", 0, CRYPTO_ALG_ASYNC); |
---|
34 | | - if (IS_ERR(local->wep_tx_tfm)) { |
---|
35 | | - local->wep_rx_tfm = ERR_PTR(-EINVAL); |
---|
36 | | - return PTR_ERR(local->wep_tx_tfm); |
---|
37 | | - } |
---|
38 | | - |
---|
39 | | - local->wep_rx_tfm = crypto_alloc_cipher("arc4", 0, CRYPTO_ALG_ASYNC); |
---|
40 | | - if (IS_ERR(local->wep_rx_tfm)) { |
---|
41 | | - crypto_free_cipher(local->wep_tx_tfm); |
---|
42 | | - local->wep_tx_tfm = ERR_PTR(-EINVAL); |
---|
43 | | - return PTR_ERR(local->wep_rx_tfm); |
---|
44 | | - } |
---|
45 | | - |
---|
46 | | - return 0; |
---|
47 | | -} |
---|
48 | | - |
---|
49 | | -void ieee80211_wep_free(struct ieee80211_local *local) |
---|
50 | | -{ |
---|
51 | | - if (!IS_ERR(local->wep_tx_tfm)) |
---|
52 | | - crypto_free_cipher(local->wep_tx_tfm); |
---|
53 | | - if (!IS_ERR(local->wep_rx_tfm)) |
---|
54 | | - crypto_free_cipher(local->wep_rx_tfm); |
---|
55 | 29 | } |
---|
56 | 30 | |
---|
57 | 31 | static inline bool ieee80211_wep_weak_iv(u32 iv, int keylen) |
---|
.. | .. |
---|
131 | 105 | /* Perform WEP encryption using given key. data buffer must have tailroom |
---|
132 | 106 | * for 4-byte ICV. data_len must not include this ICV. Note: this function |
---|
133 | 107 | * does _not_ add IV. data = RC4(data | CRC32(data)) */ |
---|
134 | | -int ieee80211_wep_encrypt_data(struct crypto_cipher *tfm, u8 *rc4key, |
---|
| 108 | +int ieee80211_wep_encrypt_data(struct arc4_ctx *ctx, u8 *rc4key, |
---|
135 | 109 | size_t klen, u8 *data, size_t data_len) |
---|
136 | 110 | { |
---|
137 | 111 | __le32 icv; |
---|
138 | | - int i; |
---|
139 | | - |
---|
140 | | - if (IS_ERR(tfm)) |
---|
141 | | - return -1; |
---|
142 | 112 | |
---|
143 | 113 | icv = cpu_to_le32(~crc32_le(~0, data, data_len)); |
---|
144 | 114 | put_unaligned(icv, (__le32 *)(data + data_len)); |
---|
145 | 115 | |
---|
146 | | - crypto_cipher_setkey(tfm, rc4key, klen); |
---|
147 | | - for (i = 0; i < data_len + IEEE80211_WEP_ICV_LEN; i++) |
---|
148 | | - crypto_cipher_encrypt_one(tfm, data + i, data + i); |
---|
| 116 | + arc4_setkey(ctx, rc4key, klen); |
---|
| 117 | + arc4_crypt(ctx, data, data, data_len + IEEE80211_WEP_ICV_LEN); |
---|
| 118 | + memzero_explicit(ctx, sizeof(*ctx)); |
---|
149 | 119 | |
---|
150 | 120 | return 0; |
---|
151 | 121 | } |
---|
.. | .. |
---|
184 | 154 | /* Add room for ICV */ |
---|
185 | 155 | skb_put(skb, IEEE80211_WEP_ICV_LEN); |
---|
186 | 156 | |
---|
187 | | - return ieee80211_wep_encrypt_data(local->wep_tx_tfm, rc4key, keylen + 3, |
---|
| 157 | + return ieee80211_wep_encrypt_data(&local->wep_tx_ctx, rc4key, keylen + 3, |
---|
188 | 158 | iv + IEEE80211_WEP_IV_LEN, len); |
---|
189 | 159 | } |
---|
190 | 160 | |
---|
.. | .. |
---|
192 | 162 | /* Perform WEP decryption using given key. data buffer includes encrypted |
---|
193 | 163 | * payload, including 4-byte ICV, but _not_ IV. data_len must not include ICV. |
---|
194 | 164 | * Return 0 on success and -1 on ICV mismatch. */ |
---|
195 | | -int ieee80211_wep_decrypt_data(struct crypto_cipher *tfm, u8 *rc4key, |
---|
| 165 | +int ieee80211_wep_decrypt_data(struct arc4_ctx *ctx, u8 *rc4key, |
---|
196 | 166 | size_t klen, u8 *data, size_t data_len) |
---|
197 | 167 | { |
---|
198 | 168 | __le32 crc; |
---|
199 | | - int i; |
---|
200 | 169 | |
---|
201 | | - if (IS_ERR(tfm)) |
---|
202 | | - return -1; |
---|
203 | | - |
---|
204 | | - crypto_cipher_setkey(tfm, rc4key, klen); |
---|
205 | | - for (i = 0; i < data_len + IEEE80211_WEP_ICV_LEN; i++) |
---|
206 | | - crypto_cipher_decrypt_one(tfm, data + i, data + i); |
---|
| 170 | + arc4_setkey(ctx, rc4key, klen); |
---|
| 171 | + arc4_crypt(ctx, data, data, data_len + IEEE80211_WEP_ICV_LEN); |
---|
| 172 | + memzero_explicit(ctx, sizeof(*ctx)); |
---|
207 | 173 | |
---|
208 | 174 | crc = cpu_to_le32(~crc32_le(~0, data, data_len)); |
---|
209 | 175 | if (memcmp(&crc, data + data_len, IEEE80211_WEP_ICV_LEN) != 0) |
---|
.. | .. |
---|
256 | 222 | /* Copy rest of the WEP key (the secret part) */ |
---|
257 | 223 | memcpy(rc4key + 3, key->conf.key, key->conf.keylen); |
---|
258 | 224 | |
---|
259 | | - if (ieee80211_wep_decrypt_data(local->wep_rx_tfm, rc4key, klen, |
---|
| 225 | + if (ieee80211_wep_decrypt_data(&local->wep_rx_ctx, rc4key, klen, |
---|
260 | 226 | skb->data + hdrlen + |
---|
261 | 227 | IEEE80211_WEP_IV_LEN, len)) |
---|
262 | 228 | ret = -1; |
---|