aboutsummaryrefslogtreecommitdiffstats
path: root/net/ieee80211/ieee80211_crypt_ccmp.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ieee80211/ieee80211_crypt_ccmp.c')
-rw-r--r--net/ieee80211/ieee80211_crypt_ccmp.c47
1 files changed, 16 insertions, 31 deletions
diff --git a/net/ieee80211/ieee80211_crypt_ccmp.c b/net/ieee80211/ieee80211_crypt_ccmp.c
index 11d15573b26a..8fc13f45971e 100644
--- a/net/ieee80211/ieee80211_crypt_ccmp.c
+++ b/net/ieee80211/ieee80211_crypt_ccmp.c
@@ -24,7 +24,6 @@
24 24
25#include <net/ieee80211.h> 25#include <net/ieee80211.h>
26 26
27
28#include <linux/crypto.h> 27#include <linux/crypto.h>
29#include <asm/scatterlist.h> 28#include <asm/scatterlist.h>
30 29
@@ -55,7 +54,7 @@ struct ieee80211_ccmp_data {
55 54
56 /* scratch buffers for virt_to_page() (crypto API) */ 55 /* scratch buffers for virt_to_page() (crypto API) */
57 u8 tx_b0[AES_BLOCK_LEN], tx_b[AES_BLOCK_LEN], 56 u8 tx_b0[AES_BLOCK_LEN], tx_b[AES_BLOCK_LEN],
58 tx_e[AES_BLOCK_LEN], tx_s0[AES_BLOCK_LEN]; 57 tx_e[AES_BLOCK_LEN], tx_s0[AES_BLOCK_LEN];
59 u8 rx_b0[AES_BLOCK_LEN], rx_b[AES_BLOCK_LEN], rx_a[AES_BLOCK_LEN]; 58 u8 rx_b0[AES_BLOCK_LEN], rx_b[AES_BLOCK_LEN], rx_a[AES_BLOCK_LEN];
60}; 59};
61 60
@@ -75,7 +74,7 @@ static void ieee80211_ccmp_aes_encrypt(struct crypto_tfm *tfm,
75 crypto_cipher_encrypt(tfm, &dst, &src, AES_BLOCK_LEN); 74 crypto_cipher_encrypt(tfm, &dst, &src, AES_BLOCK_LEN);
76} 75}
77 76
78static void * ieee80211_ccmp_init(int key_idx) 77static void *ieee80211_ccmp_init(int key_idx)
79{ 78{
80 struct ieee80211_ccmp_data *priv; 79 struct ieee80211_ccmp_data *priv;
81 80
@@ -94,7 +93,7 @@ static void * ieee80211_ccmp_init(int key_idx)
94 93
95 return priv; 94 return priv;
96 95
97fail: 96 fail:
98 if (priv) { 97 if (priv) {
99 if (priv->tfm) 98 if (priv->tfm)
100 crypto_free_tfm(priv->tfm); 99 crypto_free_tfm(priv->tfm);
@@ -104,7 +103,6 @@ fail:
104 return NULL; 103 return NULL;
105} 104}
106 105
107
108static void ieee80211_ccmp_deinit(void *priv) 106static void ieee80211_ccmp_deinit(void *priv)
109{ 107{
110 struct ieee80211_ccmp_data *_priv = priv; 108 struct ieee80211_ccmp_data *_priv = priv;
@@ -113,19 +111,16 @@ static void ieee80211_ccmp_deinit(void *priv)
113 kfree(priv); 111 kfree(priv);
114} 112}
115 113
116 114static inline void xor_block(u8 * b, u8 * a, size_t len)
117static inline void xor_block(u8 *b, u8 *a, size_t len)
118{ 115{
119 int i; 116 int i;
120 for (i = 0; i < len; i++) 117 for (i = 0; i < len; i++)
121 b[i] ^= a[i]; 118 b[i] ^= a[i];
122} 119}
123 120
124
125static void ccmp_init_blocks(struct crypto_tfm *tfm, 121static void ccmp_init_blocks(struct crypto_tfm *tfm,
126 struct ieee80211_hdr *hdr, 122 struct ieee80211_hdr *hdr,
127 u8 *pn, size_t dlen, u8 *b0, u8 *auth, 123 u8 * pn, size_t dlen, u8 * b0, u8 * auth, u8 * s0)
128 u8 *s0)
129{ 124{
130 u8 *pos, qc = 0; 125 u8 *pos, qc = 0;
131 size_t aad_len; 126 size_t aad_len;
@@ -142,7 +137,7 @@ static void ccmp_init_blocks(struct crypto_tfm *tfm,
142 if (a4_included) 137 if (a4_included)
143 aad_len += 6; 138 aad_len += 6;
144 if (qc_included) { 139 if (qc_included) {
145 pos = (u8 *) &hdr->addr4; 140 pos = (u8 *) & hdr->addr4;
146 if (a4_included) 141 if (a4_included)
147 pos += 6; 142 pos += 6;
148 qc = *pos & 0x0f; 143 qc = *pos & 0x0f;
@@ -169,14 +164,14 @@ static void ccmp_init_blocks(struct crypto_tfm *tfm,
169 * QC (if present) 164 * QC (if present)
170 */ 165 */
171 pos = (u8 *) hdr; 166 pos = (u8 *) hdr;
172 aad[0] = 0; /* aad_len >> 8 */ 167 aad[0] = 0; /* aad_len >> 8 */
173 aad[1] = aad_len & 0xff; 168 aad[1] = aad_len & 0xff;
174 aad[2] = pos[0] & 0x8f; 169 aad[2] = pos[0] & 0x8f;
175 aad[3] = pos[1] & 0xc7; 170 aad[3] = pos[1] & 0xc7;
176 memcpy(aad + 4, hdr->addr1, 3 * ETH_ALEN); 171 memcpy(aad + 4, hdr->addr1, 3 * ETH_ALEN);
177 pos = (u8 *) &hdr->seq_ctl; 172 pos = (u8 *) & hdr->seq_ctl;
178 aad[22] = pos[0] & 0x0f; 173 aad[22] = pos[0] & 0x0f;
179 aad[23] = 0; /* all bits masked */ 174 aad[23] = 0; /* all bits masked */
180 memset(aad + 24, 0, 8); 175 memset(aad + 24, 0, 8);
181 if (a4_included) 176 if (a4_included)
182 memcpy(aad + 24, hdr->addr4, ETH_ALEN); 177 memcpy(aad + 24, hdr->addr4, ETH_ALEN);
@@ -196,7 +191,6 @@ static void ccmp_init_blocks(struct crypto_tfm *tfm,
196 ieee80211_ccmp_aes_encrypt(tfm, b0, s0); 191 ieee80211_ccmp_aes_encrypt(tfm, b0, s0);
197} 192}
198 193
199
200static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv) 194static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
201{ 195{
202 struct ieee80211_ccmp_data *key = priv; 196 struct ieee80211_ccmp_data *key = priv;
@@ -209,8 +203,7 @@ static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
209 u8 *s0 = key->tx_s0; 203 u8 *s0 = key->tx_s0;
210 204
211 if (skb_headroom(skb) < CCMP_HDR_LEN || 205 if (skb_headroom(skb) < CCMP_HDR_LEN ||
212 skb_tailroom(skb) < CCMP_MIC_LEN || 206 skb_tailroom(skb) < CCMP_MIC_LEN || skb->len < hdr_len)
213 skb->len < hdr_len)
214 return -1; 207 return -1;
215 208
216 data_len = skb->len - hdr_len; 209 data_len = skb->len - hdr_len;
@@ -230,13 +223,13 @@ static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
230 *pos++ = key->tx_pn[5]; 223 *pos++ = key->tx_pn[5];
231 *pos++ = key->tx_pn[4]; 224 *pos++ = key->tx_pn[4];
232 *pos++ = 0; 225 *pos++ = 0;
233 *pos++ = (key->key_idx << 6) | (1 << 5) /* Ext IV included */; 226 *pos++ = (key->key_idx << 6) | (1 << 5) /* Ext IV included */ ;
234 *pos++ = key->tx_pn[3]; 227 *pos++ = key->tx_pn[3];
235 *pos++ = key->tx_pn[2]; 228 *pos++ = key->tx_pn[2];
236 *pos++ = key->tx_pn[1]; 229 *pos++ = key->tx_pn[1];
237 *pos++ = key->tx_pn[0]; 230 *pos++ = key->tx_pn[0];
238 231
239 hdr = (struct ieee80211_hdr *) skb->data; 232 hdr = (struct ieee80211_hdr *)skb->data;
240 ccmp_init_blocks(key->tfm, hdr, key->tx_pn, data_len, b0, b, s0); 233 ccmp_init_blocks(key->tfm, hdr, key->tx_pn, data_len, b0, b, s0);
241 234
242 blocks = (data_len + AES_BLOCK_LEN - 1) / AES_BLOCK_LEN; 235 blocks = (data_len + AES_BLOCK_LEN - 1) / AES_BLOCK_LEN;
@@ -261,7 +254,6 @@ static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
261 return 0; 254 return 0;
262} 255}
263 256
264
265static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv) 257static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
266{ 258{
267 struct ieee80211_ccmp_data *key = priv; 259 struct ieee80211_ccmp_data *key = priv;
@@ -280,7 +272,7 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
280 return -1; 272 return -1;
281 } 273 }
282 274
283 hdr = (struct ieee80211_hdr *) skb->data; 275 hdr = (struct ieee80211_hdr *)skb->data;
284 pos = skb->data + hdr_len; 276 pos = skb->data + hdr_len;
285 keyidx = pos[3]; 277 keyidx = pos[3];
286 if (!(keyidx & (1 << 5))) { 278 if (!(keyidx & (1 << 5))) {
@@ -364,8 +356,7 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
364 return keyidx; 356 return keyidx;
365} 357}
366 358
367 359static int ieee80211_ccmp_set_key(void *key, int len, u8 * seq, void *priv)
368static int ieee80211_ccmp_set_key(void *key, int len, u8 *seq, void *priv)
369{ 360{
370 struct ieee80211_ccmp_data *data = priv; 361 struct ieee80211_ccmp_data *data = priv;
371 int keyidx; 362 int keyidx;
@@ -395,8 +386,7 @@ static int ieee80211_ccmp_set_key(void *key, int len, u8 *seq, void *priv)
395 return 0; 386 return 0;
396} 387}
397 388
398 389static int ieee80211_ccmp_get_key(void *key, int len, u8 * seq, void *priv)
399static int ieee80211_ccmp_get_key(void *key, int len, u8 *seq, void *priv)
400{ 390{
401 struct ieee80211_ccmp_data *data = priv; 391 struct ieee80211_ccmp_data *data = priv;
402 392
@@ -419,8 +409,7 @@ static int ieee80211_ccmp_get_key(void *key, int len, u8 *seq, void *priv)
419 return CCMP_TK_LEN; 409 return CCMP_TK_LEN;
420} 410}
421 411
422 412static char *ieee80211_ccmp_print_stats(char *p, void *priv)
423static char * ieee80211_ccmp_print_stats(char *p, void *priv)
424{ 413{
425 struct ieee80211_ccmp_data *ccmp = priv; 414 struct ieee80211_ccmp_data *ccmp = priv;
426 p += sprintf(p, "key[%d] alg=CCMP key_set=%d " 415 p += sprintf(p, "key[%d] alg=CCMP key_set=%d "
@@ -436,7 +425,6 @@ static char * ieee80211_ccmp_print_stats(char *p, void *priv)
436 return p; 425 return p;
437} 426}
438 427
439
440static struct ieee80211_crypto_ops ieee80211_crypt_ccmp = { 428static struct ieee80211_crypto_ops ieee80211_crypt_ccmp = {
441 .name = "CCMP", 429 .name = "CCMP",
442 .init = ieee80211_ccmp_init, 430 .init = ieee80211_ccmp_init,
@@ -453,18 +441,15 @@ static struct ieee80211_crypto_ops ieee80211_crypt_ccmp = {
453 .owner = THIS_MODULE, 441 .owner = THIS_MODULE,
454}; 442};
455 443
456
457static int __init ieee80211_crypto_ccmp_init(void) 444static int __init ieee80211_crypto_ccmp_init(void)
458{ 445{
459 return ieee80211_register_crypto_ops(&ieee80211_crypt_ccmp); 446 return ieee80211_register_crypto_ops(&ieee80211_crypt_ccmp);
460} 447}
461 448
462
463static void __exit ieee80211_crypto_ccmp_exit(void) 449static void __exit ieee80211_crypto_ccmp_exit(void)
464{ 450{
465 ieee80211_unregister_crypto_ops(&ieee80211_crypt_ccmp); 451 ieee80211_unregister_crypto_ops(&ieee80211_crypt_ccmp);
466} 452}
467 453
468
469module_init(ieee80211_crypto_ccmp_init); 454module_init(ieee80211_crypto_ccmp_init);
470module_exit(ieee80211_crypto_ccmp_exit); 455module_exit(ieee80211_crypto_ccmp_exit);