wpa.c 20.5 KB
Newer Older
1 2
/*
 * Copyright 2002-2004, Instant802 Networks, Inc.
3
 * Copyright 2008, Jouni Malinen <j@w1.fi>
4 5 6 7 8 9 10 11 12 13
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#include <linux/netdevice.h>
#include <linux/types.h>
#include <linux/skbuff.h>
#include <linux/compiler.h>
14
#include <linux/ieee80211.h>
15
#include <linux/gfp.h>
16
#include <asm/unaligned.h>
17
#include <net/mac80211.h>
J
Johannes Berg 已提交
18
#include <crypto/aes.h>
J
Johannes Berg 已提交
19

20 21 22 23
#include "ieee80211_i.h"
#include "michael.h"
#include "tkip.h"
#include "aes_ccm.h"
24
#include "aes_cmac.h"
25 26
#include "wpa.h"

27
ieee80211_tx_result
28
ieee80211_tx_h_michael_mic_add(struct ieee80211_tx_data *tx)
29
{
30
	u8 *data, *key, *mic;
31
	size_t data_len;
32 33
	unsigned int hdrlen;
	struct ieee80211_hdr *hdr;
34
	struct sk_buff *skb = tx->skb;
35
	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
36
	int tail;
37

38
	hdr = (struct ieee80211_hdr *)skb->data;
39 40
	if (!tx->key || tx->key->conf.cipher != WLAN_CIPHER_SUITE_TKIP ||
	    skb->len < 24 || !ieee80211_is_data_present(hdr->frame_control))
41
		return TX_CONTINUE;
42

43 44
	hdrlen = ieee80211_hdrlen(hdr->frame_control);
	if (skb->len < hdrlen)
45
		return TX_DROP;
46

47 48 49
	data = skb->data + hdrlen;
	data_len = skb->len - hdrlen;

50 51 52 53 54
	if (unlikely(info->flags & IEEE80211_TX_INTFL_TKIP_MIC_FAILURE)) {
		/* Need to use software crypto for the test */
		info->control.hw_key = NULL;
	}

55
	if (info->control.hw_key &&
56 57
	    (info->flags & IEEE80211_TX_CTL_DONTFRAG ||
	     tx->local->ops->set_frag_threshold) &&
58 59
	    !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC)) {
		/* hwaccel - with no need for SW-generated MMIC */
60
		return TX_CONTINUE;
61 62
	}

63
	tail = MICHAEL_MIC_LEN;
64
	if (!info->control.hw_key)
65
		tail += IEEE80211_TKIP_ICV_LEN;
66

67 68 69 70 71
	if (WARN(skb_tailroom(skb) < tail ||
		 skb_headroom(skb) < IEEE80211_TKIP_IV_LEN,
		 "mmic: not enough head/tail (%d/%d,%d/%d)\n",
		 skb_headroom(skb), IEEE80211_TKIP_IV_LEN,
		 skb_tailroom(skb), tail))
72
		return TX_DROP;
73

74
	key = &tx->key->conf.key[NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY];
75
	mic = skb_put(skb, MICHAEL_MIC_LEN);
76
	michael_mic(key, hdr, data, data_len, mic);
77 78
	if (unlikely(info->flags & IEEE80211_TX_INTFL_TKIP_MIC_FAILURE))
		mic[0]++;
79

80
	return TX_CONTINUE;
81 82 83
}


84
ieee80211_rx_result
85
ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx)
86
{
87
	u8 *data, *key = NULL;
88
	size_t data_len;
89
	unsigned int hdrlen;
90 91
	u8 mic[MICHAEL_MIC_LEN];
	struct sk_buff *skb = rx->skb;
J
Johannes Berg 已提交
92 93
	struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
94

95 96 97 98 99
	/*
	 * it makes no sense to check for MIC errors on anything other
	 * than data frames.
	 */
	if (!ieee80211_is_data_present(hdr->frame_control))
100
		return RX_CONTINUE;
101

102 103 104 105 106 107 108 109
	/*
	 * No way to verify the MIC if the hardware stripped it or
	 * the IV with the key index. In this case we have solely rely
	 * on the driver to set RX_FLAG_MMIC_ERROR in the event of a
	 * MIC failure report.
	 */
	if (status->flag & (RX_FLAG_MMIC_STRIPPED | RX_FLAG_IV_STRIPPED)) {
		if (status->flag & RX_FLAG_MMIC_ERROR)
110
			goto mic_fail_no_key;
111

112 113
		if (!(status->flag & RX_FLAG_IV_STRIPPED) && rx->key &&
		    rx->key->conf.cipher == WLAN_CIPHER_SUITE_TKIP)
114 115 116 117 118 119 120 121 122 123
			goto update_iv;

		return RX_CONTINUE;
	}

	/*
	 * Some hardware seems to generate Michael MIC failure reports; even
	 * though, the frame was not encrypted with TKIP and therefore has no
	 * MIC. Ignore the flag them to avoid triggering countermeasures.
	 */
124
	if (!rx->key || rx->key->conf.cipher != WLAN_CIPHER_SUITE_TKIP ||
125
	    !(status->flag & RX_FLAG_DECRYPTED))
126
		return RX_CONTINUE;
127

128 129 130 131 132
	if (rx->sdata->vif.type == NL80211_IFTYPE_AP && rx->key->conf.keyidx) {
		/*
		 * APs with pairwise keys should never receive Michael MIC
		 * errors for non-zero keyidx because these are reserved for
		 * group keys and only the AP is sending real multicast
133
		 * frames in the BSS.
134 135 136 137 138 139 140
		 */
		return RX_DROP_UNUSABLE;
	}

	if (status->flag & RX_FLAG_MMIC_ERROR)
		goto mic_fail;

141 142
	hdrlen = ieee80211_hdrlen(hdr->frame_control);
	if (skb->len < hdrlen + MICHAEL_MIC_LEN)
J
Johannes Berg 已提交
143
		return RX_DROP_UNUSABLE;
144

145 146 147 148
	if (skb_linearize(rx->skb))
		return RX_DROP_UNUSABLE;
	hdr = (void *)skb->data;

149 150
	data = skb->data + hdrlen;
	data_len = skb->len - hdrlen - MICHAEL_MIC_LEN;
151
	key = &rx->key->conf.key[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY];
152
	michael_mic(key, hdr, data, data_len, mic);
153 154
	if (memcmp(mic, data + data_len, MICHAEL_MIC_LEN) != 0)
		goto mic_fail;
155 156 157 158

	/* remove Michael MIC from payload */
	skb_trim(skb, skb->len - MICHAEL_MIC_LEN);

159
update_iv:
160
	/* update IV in key information to be able to detect replays */
161 162
	rx->key->u.tkip.rx[rx->security_idx].iv32 = rx->tkip_iv32;
	rx->key->u.tkip.rx[rx->security_idx].iv16 = rx->tkip_iv16;
163

164
	return RX_CONTINUE;
165 166

mic_fail:
167 168 169
	rx->key->u.tkip.mic_failures++;

mic_fail_no_key:
170 171 172 173 174 175 176
	/*
	 * In some cases the key can be unset - e.g. a multicast packet, in
	 * a driver that supports HW encryption. Send up the key idx only if
	 * the key is set.
	 */
	mac80211_ev_michael_mic_failure(rx->sdata,
					rx->key ? rx->key->conf.keyidx : -1,
177 178
					(void *) skb->data, NULL, GFP_ATOMIC);
	return RX_DROP_UNUSABLE;
179 180 181
}


182
static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
183 184 185
{
	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
	struct ieee80211_key *key = tx->key;
186
	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
187 188
	unsigned int hdrlen;
	int len, tail;
189 190
	u8 *pos;

191
	if (info->control.hw_key &&
192 193
	    !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV) &&
	    !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE)) {
194
		/* hwaccel - with no need for software-generated IV */
195
		return 0;
196 197
	}

198
	hdrlen = ieee80211_hdrlen(hdr->frame_control);
199 200
	len = skb->len - hdrlen;

201
	if (info->control.hw_key)
202
		tail = 0;
J
Johannes Berg 已提交
203
	else
204
		tail = IEEE80211_TKIP_ICV_LEN;
205 206

	if (WARN_ON(skb_tailroom(skb) < tail ||
207
		    skb_headroom(skb) < IEEE80211_TKIP_IV_LEN))
208
		return -1;
209

210 211
	pos = skb_push(skb, IEEE80211_TKIP_IV_LEN);
	memmove(pos, pos + IEEE80211_TKIP_IV_LEN, hdrlen);
212 213
	pos += hdrlen;

214 215 216 217 218
	/* the HW only needs room for the IV, but not the actual IV */
	if (info->control.hw_key &&
	    (info->control.hw_key->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE))
		return 0;

219
	/* Increase IV for the frame */
220
	spin_lock(&key->u.tkip.txlock);
221 222 223
	key->u.tkip.tx.iv16++;
	if (key->u.tkip.tx.iv16 == 0)
		key->u.tkip.tx.iv32++;
224
	pos = ieee80211_tkip_add_iv(pos, key);
225
	spin_unlock(&key->u.tkip.txlock);
226

227 228
	/* hwaccel - with software IV */
	if (info->control.hw_key)
229 230 231
		return 0;

	/* Add room for ICV */
232
	skb_put(skb, IEEE80211_TKIP_ICV_LEN);
233

234
	return ieee80211_tkip_encrypt_data(tx->local->wep_tx_tfm,
235
					   key, skb, pos, len);
236 237 238
}


239
ieee80211_tx_result
240
ieee80211_crypto_tkip_encrypt(struct ieee80211_tx_data *tx)
241
{
242
	struct sk_buff *skb;
243

244
	ieee80211_tx_set_protected(tx);
245

246
	skb_queue_walk(&tx->skbs, skb) {
J
Johannes Berg 已提交
247 248
		if (tkip_encrypt_skb(tx, skb) < 0)
			return TX_DROP;
249
	}
250

251
	return TX_CONTINUE;
252 253 254
}


255
ieee80211_rx_result
256
ieee80211_crypto_tkip_decrypt(struct ieee80211_rx_data *rx)
257 258
{
	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data;
259
	int hdrlen, res, hwaccel = 0;
260 261
	struct ieee80211_key *key = rx->key;
	struct sk_buff *skb = rx->skb;
J
Johannes Berg 已提交
262
	struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
263

264
	hdrlen = ieee80211_hdrlen(hdr->frame_control);
265

266
	if (!ieee80211_is_data(hdr->frame_control))
267
		return RX_CONTINUE;
268 269

	if (!rx->sta || skb->len - hdrlen < 12)
J
Johannes Berg 已提交
270
		return RX_DROP_UNUSABLE;
271

272 273 274 275 276
	/* it may be possible to optimize this a bit more */
	if (skb_linearize(rx->skb))
		return RX_DROP_UNUSABLE;
	hdr = (void *)skb->data;

277 278 279 280 281 282
	/*
	 * Let TKIP code verify IV, but skip decryption.
	 * In the case where hardware checks the IV as well,
	 * we don't even get here, see ieee80211_rx_h_decrypt()
	 */
	if (status->flag & RX_FLAG_DECRYPTED)
283 284 285 286
		hwaccel = 1;

	res = ieee80211_tkip_decrypt_data(rx->local->wep_rx_tfm,
					  key, skb->data + hdrlen,
287
					  skb->len - hdrlen, rx->sta->sta.addr,
288
					  hdr->addr1, hwaccel, rx->security_idx,
289 290
					  &rx->tkip_iv32,
					  &rx->tkip_iv16);
291
	if (res != TKIP_DECRYPT_OK)
J
Johannes Berg 已提交
292
		return RX_DROP_UNUSABLE;
293 294

	/* Trim ICV */
295
	skb_trim(skb, skb->len - IEEE80211_TKIP_ICV_LEN);
296 297

	/* Remove IV */
298 299
	memmove(skb->data + IEEE80211_TKIP_IV_LEN, skb->data, hdrlen);
	skb_pull(skb, IEEE80211_TKIP_IV_LEN);
300

301
	return RX_CONTINUE;
302 303 304
}


305
static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *b_0, u8 *aad)
306
{
307
	__le16 mask_fc;
308
	int a4_included, mgmt;
309
	u8 qos_tid;
310
	u16 len_a;
311 312
	unsigned int hdrlen;
	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
313

314
	/*
315
	 * Mask FC: zero subtype b4 b5 b6 (if not mgmt)
316 317
	 * Retry, PwrMgt, MoreData; set Protected
	 */
318
	mgmt = ieee80211_is_mgmt(hdr->frame_control);
319
	mask_fc = hdr->frame_control;
320
	mask_fc &= ~cpu_to_le16(IEEE80211_FCTL_RETRY |
321
				IEEE80211_FCTL_PM | IEEE80211_FCTL_MOREDATA);
322 323
	if (!mgmt)
		mask_fc &= ~cpu_to_le16(0x0070);
324 325 326 327 328
	mask_fc |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);

	hdrlen = ieee80211_hdrlen(hdr->frame_control);
	len_a = hdrlen - 2;
	a4_included = ieee80211_has_a4(hdr->frame_control);
329

330 331 332 333 334
	if (ieee80211_is_data_qos(hdr->frame_control))
		qos_tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK;
	else
		qos_tid = 0;

335 336 337 338 339 340 341 342
	/* In CCM, the initial vectors (IV) used for CTR mode encryption and CBC
	 * mode authentication are not allowed to collide, yet both are derived
	 * from this vector b_0. We only set L := 1 here to indicate that the
	 * data size can be represented in (L+1) bytes. The CCM layer will take
	 * care of storing the data length in the top (L+1) bytes and setting
	 * and clearing the other bits as is required to derive the two IVs.
	 */
	b_0[0] = 0x1;
343

344 345 346 347
	/* Nonce: Nonce Flags | A2 | PN
	 * Nonce Flags: Priority (b0..b3) | Management (b4) | Reserved (b5..b7)
	 */
	b_0[1] = qos_tid | (mgmt << 4);
348
	memcpy(&b_0[2], hdr->addr2, ETH_ALEN);
349
	memcpy(&b_0[8], pn, IEEE80211_CCMP_PN_LEN);
350 351 352

	/* AAD (extra authenticate-only data) / masked 802.11 header
	 * FC | A1 | A2 | A3 | SC | [A4] | [QC] */
353 354
	put_unaligned_be16(len_a, &aad[0]);
	put_unaligned(mask_fc, (__le16 *)&aad[2]);
355
	memcpy(&aad[4], &hdr->addr1, 3 * ETH_ALEN);
356 357 358 359

	/* Mask Seq#, leave Frag# */
	aad[22] = *((u8 *) &hdr->seq_ctrl) & 0x0f;
	aad[23] = 0;
360

361
	if (a4_included) {
362
		memcpy(&aad[24], hdr->addr4, ETH_ALEN);
363
		aad[30] = qos_tid;
364
		aad[31] = 0;
365
	} else {
366
		memset(&aad[24], 0, ETH_ALEN + IEEE80211_QOS_CTL_LEN);
367
		aad[24] = qos_tid;
368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384
	}
}


static inline void ccmp_pn2hdr(u8 *hdr, u8 *pn, int key_id)
{
	hdr[0] = pn[5];
	hdr[1] = pn[4];
	hdr[2] = 0;
	hdr[3] = 0x20 | (key_id << 6);
	hdr[4] = pn[3];
	hdr[5] = pn[2];
	hdr[6] = pn[1];
	hdr[7] = pn[0];
}


J
Johannes Berg 已提交
385
static inline void ccmp_hdr2pn(u8 *pn, u8 *hdr)
386 387 388 389 390 391 392 393 394 395
{
	pn[0] = hdr[7];
	pn[1] = hdr[6];
	pn[2] = hdr[5];
	pn[3] = hdr[4];
	pn[4] = hdr[1];
	pn[5] = hdr[0];
}


396
static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
397 398 399
{
	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
	struct ieee80211_key *key = tx->key;
400
	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
401
	int hdrlen, len, tail;
J
Johannes Berg 已提交
402 403 404
	u8 *pos;
	u8 pn[6];
	u64 pn64;
405 406
	u8 aad[2 * AES_BLOCK_SIZE];
	u8 b_0[AES_BLOCK_SIZE];
407

408
	if (info->control.hw_key &&
409
	    !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV) &&
410 411 412 413
	    !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE) &&
	    !((info->control.hw_key->flags &
	       IEEE80211_KEY_FLAG_GENERATE_IV_MGMT) &&
	      ieee80211_is_mgmt(hdr->frame_control))) {
414 415 416 417
		/*
		 * hwaccel has no need for preallocated room for CCMP
		 * header or MIC fields
		 */
418
		return 0;
419 420
	}

421
	hdrlen = ieee80211_hdrlen(hdr->frame_control);
422 423
	len = skb->len - hdrlen;

424
	if (info->control.hw_key)
425
		tail = 0;
J
Johannes Berg 已提交
426
	else
427
		tail = IEEE80211_CCMP_MIC_LEN;
428 429

	if (WARN_ON(skb_tailroom(skb) < tail ||
430
		    skb_headroom(skb) < IEEE80211_CCMP_HDR_LEN))
431
		return -1;
432

433 434
	pos = skb_push(skb, IEEE80211_CCMP_HDR_LEN);
	memmove(pos, pos + IEEE80211_CCMP_HDR_LEN, hdrlen);
435 436

	/* the HW only needs room for the IV, but not the actual IV */
437 438
	if (info->control.hw_key &&
	    (info->control.hw_key->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE))
439 440
		return 0;

441 442 443
	hdr = (struct ieee80211_hdr *) pos;
	pos += hdrlen;

J
Johannes Berg 已提交
444
	pn64 = atomic64_inc_return(&key->u.ccmp.tx_pn);
445

J
Johannes Berg 已提交
446 447 448 449 450 451
	pn[5] = pn64;
	pn[4] = pn64 >> 8;
	pn[3] = pn64 >> 16;
	pn[2] = pn64 >> 24;
	pn[1] = pn64 >> 32;
	pn[0] = pn64 >> 40;
452

453
	ccmp_pn2hdr(pos, pn, key->conf.keyidx);
454

455 456
	/* hwaccel - with software CCMP header */
	if (info->control.hw_key)
457 458
		return 0;

459
	pos += IEEE80211_CCMP_HDR_LEN;
460
	ccmp_special_blocks(skb, pn, b_0, aad);
461 462
	ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, b_0, aad, pos, len,
				  skb_put(skb, IEEE80211_CCMP_MIC_LEN));
463 464 465 466 467

	return 0;
}


468
ieee80211_tx_result
469
ieee80211_crypto_ccmp_encrypt(struct ieee80211_tx_data *tx)
470
{
471
	struct sk_buff *skb;
472

473
	ieee80211_tx_set_protected(tx);
474

475
	skb_queue_walk(&tx->skbs, skb) {
J
Johannes Berg 已提交
476 477
		if (ccmp_encrypt_skb(tx, skb) < 0)
			return TX_DROP;
478
	}
479

480
	return TX_CONTINUE;
481 482 483
}


484
ieee80211_rx_result
485
ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx)
486
{
487
	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data;
488 489 490
	int hdrlen;
	struct ieee80211_key *key = rx->key;
	struct sk_buff *skb = rx->skb;
J
Johannes Berg 已提交
491
	struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
492
	u8 pn[IEEE80211_CCMP_PN_LEN];
493
	int data_len;
494
	int queue;
495

496
	hdrlen = ieee80211_hdrlen(hdr->frame_control);
497

498
	if (!ieee80211_is_data(hdr->frame_control) &&
499
	    !ieee80211_is_robust_mgmt_frame(skb))
500
		return RX_CONTINUE;
501

502 503
	data_len = skb->len - hdrlen - IEEE80211_CCMP_HDR_LEN -
		   IEEE80211_CCMP_MIC_LEN;
504
	if (!rx->sta || data_len < 0)
J
Johannes Berg 已提交
505
		return RX_DROP_UNUSABLE;
506

507
	if (status->flag & RX_FLAG_DECRYPTED) {
508
		if (!pskb_may_pull(rx->skb, hdrlen + IEEE80211_CCMP_HDR_LEN))
509 510 511 512 513 514
			return RX_DROP_UNUSABLE;
	} else {
		if (skb_linearize(rx->skb))
			return RX_DROP_UNUSABLE;
	}

J
Johannes Berg 已提交
515
	ccmp_hdr2pn(pn, skb->data + hdrlen);
516

517
	queue = rx->security_idx;
518

519
	if (memcmp(pn, key->u.ccmp.rx_pn[queue], IEEE80211_CCMP_PN_LEN) <= 0) {
520
		key->u.ccmp.replays++;
J
Johannes Berg 已提交
521
		return RX_DROP_UNUSABLE;
522 523
	}

J
Johannes Berg 已提交
524
	if (!(status->flag & RX_FLAG_DECRYPTED)) {
525 526
		u8 aad[2 * AES_BLOCK_SIZE];
		u8 b_0[AES_BLOCK_SIZE];
527
		/* hardware didn't decrypt/verify MIC */
528
		ccmp_special_blocks(skb, pn, b_0, aad);
529 530

		if (ieee80211_aes_ccm_decrypt(
531
			    key->u.ccmp.tfm, b_0, aad,
532 533
			    skb->data + hdrlen + IEEE80211_CCMP_HDR_LEN,
			    data_len,
534
			    skb->data + skb->len - IEEE80211_CCMP_MIC_LEN))
J
Johannes Berg 已提交
535
			return RX_DROP_UNUSABLE;
536 537
	}

538
	memcpy(key->u.ccmp.rx_pn[queue], pn, IEEE80211_CCMP_PN_LEN);
539 540

	/* Remove CCMP header and MIC */
541
	if (pskb_trim(skb, skb->len - IEEE80211_CCMP_MIC_LEN))
542
		return RX_DROP_UNUSABLE;
543 544
	memmove(skb->data + IEEE80211_CCMP_HDR_LEN, skb->data, hdrlen);
	skb_pull(skb, IEEE80211_CCMP_HDR_LEN);
545

546
	return RX_CONTINUE;
547
}
548

549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647
static ieee80211_tx_result
ieee80211_crypto_cs_encrypt(struct ieee80211_tx_data *tx,
			    struct sk_buff *skb)
{
	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
	struct ieee80211_key *key = tx->key;
	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
	const struct ieee80211_cipher_scheme *cs = key->sta->cipher_scheme;
	int hdrlen;
	u8 *pos;

	if (info->control.hw_key &&
	    !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE)) {
		/* hwaccel has no need for preallocated head room */
		return TX_CONTINUE;
	}

	if (unlikely(skb_headroom(skb) < cs->hdr_len &&
		     pskb_expand_head(skb, cs->hdr_len, 0, GFP_ATOMIC)))
		return TX_DROP;

	hdrlen = ieee80211_hdrlen(hdr->frame_control);

	pos = skb_push(skb, cs->hdr_len);
	memmove(pos, pos + cs->hdr_len, hdrlen);

	return TX_CONTINUE;
}

static inline int ieee80211_crypto_cs_pn_compare(u8 *pn1, u8 *pn2, int len)
{
	int i;

	/* pn is little endian */
	for (i = len - 1; i >= 0; i--) {
		if (pn1[i] < pn2[i])
			return -1;
		else if (pn1[i] > pn2[i])
			return 1;
	}

	return 0;
}

static ieee80211_rx_result
ieee80211_crypto_cs_decrypt(struct ieee80211_rx_data *rx)
{
	struct ieee80211_key *key = rx->key;
	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data;
	const struct ieee80211_cipher_scheme *cs = NULL;
	int hdrlen = ieee80211_hdrlen(hdr->frame_control);
	struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
	int data_len;
	u8 *rx_pn;
	u8 *skb_pn;
	u8 qos_tid;

	if (!rx->sta || !rx->sta->cipher_scheme ||
	    !(status->flag & RX_FLAG_DECRYPTED))
		return RX_DROP_UNUSABLE;

	if (!ieee80211_is_data(hdr->frame_control))
		return RX_CONTINUE;

	cs = rx->sta->cipher_scheme;

	data_len = rx->skb->len - hdrlen - cs->hdr_len;

	if (data_len < 0)
		return RX_DROP_UNUSABLE;

	if (ieee80211_is_data_qos(hdr->frame_control))
		qos_tid = *ieee80211_get_qos_ctl(hdr) &
				IEEE80211_QOS_CTL_TID_MASK;
	else
		qos_tid = 0;

	if (skb_linearize(rx->skb))
		return RX_DROP_UNUSABLE;

	hdr = (struct ieee80211_hdr *)rx->skb->data;

	rx_pn = key->u.gen.rx_pn[qos_tid];
	skb_pn = rx->skb->data + hdrlen + cs->pn_off;

	if (ieee80211_crypto_cs_pn_compare(skb_pn, rx_pn, cs->pn_len) <= 0)
		return RX_DROP_UNUSABLE;

	memcpy(rx_pn, skb_pn, cs->pn_len);

	/* remove security header and MIC */
	if (pskb_trim(rx->skb, rx->skb->len - cs->mic_len))
		return RX_DROP_UNUSABLE;

	memmove(rx->skb->data + cs->hdr_len, rx->skb->data, hdrlen);
	skb_pull(rx->skb, cs->hdr_len);

	return RX_CONTINUE;
}
648 649 650

static void bip_aad(struct sk_buff *skb, u8 *aad)
{
651 652 653
	__le16 mask_fc;
	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;

654 655 656 657
	/* BIP AAD: FC(masked) || A1 || A2 || A3 */

	/* FC type/subtype */
	/* Mask FC Retry, PwrMgt, MoreData flags to zero */
658 659 660 661
	mask_fc = hdr->frame_control;
	mask_fc &= ~cpu_to_le16(IEEE80211_FCTL_RETRY | IEEE80211_FCTL_PM |
				IEEE80211_FCTL_MOREDATA);
	put_unaligned(mask_fc, (__le16 *) &aad[0]);
662
	/* A1 || A2 || A3 */
663
	memcpy(aad + 2, &hdr->addr1, 3 * ETH_ALEN);
664 665 666
}


J
Johannes Berg 已提交
667 668 669 670 671 672 673 674 675 676
static inline void bip_ipn_set64(u8 *d, u64 pn)
{
	*d++ = pn;
	*d++ = pn >> 8;
	*d++ = pn >> 16;
	*d++ = pn >> 24;
	*d++ = pn >> 32;
	*d = pn >> 40;
}

677 678 679 680 681 682 683 684 685 686 687 688 689 690
static inline void bip_ipn_swap(u8 *d, const u8 *s)
{
	*d++ = s[5];
	*d++ = s[4];
	*d++ = s[3];
	*d++ = s[2];
	*d++ = s[1];
	*d = s[0];
}


ieee80211_tx_result
ieee80211_crypto_aes_cmac_encrypt(struct ieee80211_tx_data *tx)
{
691 692
	struct sk_buff *skb;
	struct ieee80211_tx_info *info;
693 694
	struct ieee80211_key *key = tx->key;
	struct ieee80211_mmie *mmie;
J
Johannes Berg 已提交
695 696
	u8 aad[20];
	u64 pn64;
697

698 699 700 701 702 703 704
	if (WARN_ON(skb_queue_len(&tx->skbs) != 1))
		return TX_DROP;

	skb = skb_peek(&tx->skbs);

	info = IEEE80211_SKB_CB(skb);

705
	if (info->control.hw_key)
706
		return TX_CONTINUE;
707 708 709 710 711 712 713 714 715 716

	if (WARN_ON(skb_tailroom(skb) < sizeof(*mmie)))
		return TX_DROP;

	mmie = (struct ieee80211_mmie *) skb_put(skb, sizeof(*mmie));
	mmie->element_id = WLAN_EID_MMIE;
	mmie->length = sizeof(*mmie) - 2;
	mmie->key_id = cpu_to_le16(key->conf.keyidx);

	/* PN = PN + 1 */
J
Johannes Berg 已提交
717
	pn64 = atomic64_inc_return(&key->u.aes_cmac.tx_pn);
718

J
Johannes Berg 已提交
719
	bip_ipn_set64(mmie->sequence_number, pn64);
720 721 722 723 724 725

	bip_aad(skb, aad);

	/*
	 * MIC = AES-128-CMAC(IGTK, AAD || Management Frame Body || MMIE, 64)
	 */
J
Johannes Berg 已提交
726 727
	ieee80211_aes_cmac(key->u.aes_cmac.tfm, aad,
			   skb->data + 24, skb->len - 24, mmie->mic);
728 729 730 731 732 733 734 735 736

	return TX_CONTINUE;
}


ieee80211_rx_result
ieee80211_crypto_aes_cmac_decrypt(struct ieee80211_rx_data *rx)
{
	struct sk_buff *skb = rx->skb;
J
Johannes Berg 已提交
737
	struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
738 739 740 741 742 743 744 745
	struct ieee80211_key *key = rx->key;
	struct ieee80211_mmie *mmie;
	u8 aad[20], mic[8], ipn[6];
	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;

	if (!ieee80211_is_mgmt(hdr->frame_control))
		return RX_CONTINUE;

746 747
	/* management frames are already linear */

748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763
	if (skb->len < 24 + sizeof(*mmie))
		return RX_DROP_UNUSABLE;

	mmie = (struct ieee80211_mmie *)
		(skb->data + skb->len - sizeof(*mmie));
	if (mmie->element_id != WLAN_EID_MMIE ||
	    mmie->length != sizeof(*mmie) - 2)
		return RX_DROP_UNUSABLE; /* Invalid MMIE */

	bip_ipn_swap(ipn, mmie->sequence_number);

	if (memcmp(ipn, key->u.aes_cmac.rx_pn, 6) <= 0) {
		key->u.aes_cmac.replays++;
		return RX_DROP_UNUSABLE;
	}

J
Johannes Berg 已提交
764
	if (!(status->flag & RX_FLAG_DECRYPTED)) {
765 766
		/* hardware didn't decrypt/verify MIC */
		bip_aad(skb, aad);
J
Johannes Berg 已提交
767
		ieee80211_aes_cmac(key->u.aes_cmac.tfm, aad,
768 769 770 771 772 773 774 775 776 777 778 779 780 781
				   skb->data + 24, skb->len - 24, mic);
		if (memcmp(mic, mmie->mic, sizeof(mmie->mic)) != 0) {
			key->u.aes_cmac.icverrors++;
			return RX_DROP_UNUSABLE;
		}
	}

	memcpy(key->u.aes_cmac.rx_pn, ipn, 6);

	/* Remove MMIE */
	skb_trim(skb, skb->len - sizeof(*mmie));

	return RX_CONTINUE;
}
782 783 784 785 786 787

ieee80211_tx_result
ieee80211_crypto_hw_encrypt(struct ieee80211_tx_data *tx)
{
	struct sk_buff *skb;
	struct ieee80211_tx_info *info = NULL;
788
	ieee80211_tx_result res;
789 790 791 792 793 794 795

	skb_queue_walk(&tx->skbs, skb) {
		info  = IEEE80211_SKB_CB(skb);

		/* handle hw-only algorithm */
		if (!info->control.hw_key)
			return TX_DROP;
796 797 798 799 800 801

		if (tx->key->sta->cipher_scheme) {
			res = ieee80211_crypto_cs_encrypt(tx, skb);
			if (res != TX_CONTINUE)
				return res;
		}
802 803 804 805 806 807
	}

	ieee80211_tx_set_protected(tx);

	return TX_CONTINUE;
}
808 809 810 811

ieee80211_rx_result
ieee80211_crypto_hw_decrypt(struct ieee80211_rx_data *rx)
{
812
	if (rx->sta && rx->sta->cipher_scheme)
813 814 815 816
		return ieee80211_crypto_cs_decrypt(rx);

	return RX_DROP_UNUSABLE;
}