wpa.c 14.2 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

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

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

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

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

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

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

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

61
	tail = MICHAEL_MIC_LEN;
62
	if (!info->control.hw_key)
63 64 65 66 67
		tail += TKIP_ICV_LEN;

	if (WARN_ON(skb_tailroom(skb) < tail ||
		    skb_headroom(skb) < TKIP_IV_LEN))
		return TX_DROP;
68

69
	key = &tx->key->conf.key[NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY];
70
	mic = skb_put(skb, MICHAEL_MIC_LEN);
71
	michael_mic(key, hdr, data, data_len, mic);
72 73
	if (unlikely(info->flags & IEEE80211_TX_INTFL_TKIP_MIC_FAILURE))
		mic[0]++;
74

75
	return TX_CONTINUE;
76 77 78
}


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

J
Johannes Berg 已提交
90
	/* No way to verify the MIC if the hardware stripped it */
J
Johannes Berg 已提交
91
	if (status->flag & RX_FLAG_MMIC_STRIPPED)
92
		return RX_CONTINUE;
93

94
	if (!rx->key || rx->key->conf.cipher != WLAN_CIPHER_SUITE_TKIP ||
95 96
	    !ieee80211_has_protected(hdr->frame_control) ||
	    !ieee80211_is_data_present(hdr->frame_control))
97
		return RX_CONTINUE;
98

99 100
	hdrlen = ieee80211_hdrlen(hdr->frame_control);
	if (skb->len < hdrlen + MICHAEL_MIC_LEN)
J
Johannes Berg 已提交
101
		return RX_DROP_UNUSABLE;
102

103 104
	data = skb->data + hdrlen;
	data_len = skb->len - hdrlen - MICHAEL_MIC_LEN;
105

106
	key = &rx->key->conf.key[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY];
107
	michael_mic(key, hdr, data, data_len, mic);
108
	if (memcmp(mic, data + data_len, MICHAEL_MIC_LEN) != 0) {
109
		if (!(status->rx_flags & IEEE80211_RX_RA_MATCH))
J
Johannes Berg 已提交
110
			return RX_DROP_UNUSABLE;
111

112
		mac80211_ev_michael_mic_failure(rx->sdata, rx->key->conf.keyidx,
113 114
						(void *) skb->data, NULL,
						GFP_ATOMIC);
J
Johannes Berg 已提交
115
		return RX_DROP_UNUSABLE;
116 117 118 119 120
	}

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

121
	/* update IV in key information to be able to detect replays */
122 123
	rx->key->u.tkip.rx[rx->queue].iv32 = rx->tkip_iv32;
	rx->key->u.tkip.rx[rx->queue].iv16 = rx->tkip_iv16;
124

125
	return RX_CONTINUE;
126 127 128
}


129
static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
130 131 132
{
	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
	struct ieee80211_key *key = tx->key;
133
	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
134 135
	unsigned int hdrlen;
	int len, tail;
136 137
	u8 *pos;

138 139 140
	if (info->control.hw_key &&
	    !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV)) {
		/* hwaccel - with no need for software-generated IV */
141
		return 0;
142 143
	}

144
	hdrlen = ieee80211_hdrlen(hdr->frame_control);
145 146
	len = skb->len - hdrlen;

147
	if (info->control.hw_key)
148
		tail = 0;
J
Johannes Berg 已提交
149
	else
150 151 152 153 154
		tail = TKIP_ICV_LEN;

	if (WARN_ON(skb_tailroom(skb) < tail ||
		    skb_headroom(skb) < TKIP_IV_LEN))
		return -1;
155 156 157 158 159 160

	pos = skb_push(skb, TKIP_IV_LEN);
	memmove(pos, pos + TKIP_IV_LEN, hdrlen);
	pos += hdrlen;

	/* Increase IV for the frame */
161 162 163
	key->u.tkip.tx.iv16++;
	if (key->u.tkip.tx.iv16 == 0)
		key->u.tkip.tx.iv32++;
164

165
	pos = ieee80211_tkip_add_iv(pos, key, key->u.tkip.tx.iv16);
166

167 168
	/* hwaccel - with software IV */
	if (info->control.hw_key)
169 170 171 172 173 174
		return 0;

	/* Add room for ICV */
	skb_put(skb, TKIP_ICV_LEN);

	hdr = (struct ieee80211_hdr *) skb->data;
175 176
	return ieee80211_tkip_encrypt_data(tx->local->wep_tx_tfm,
					   key, pos, len, hdr->addr2);
177 178 179
}


180
ieee80211_tx_result
181
ieee80211_crypto_tkip_encrypt(struct ieee80211_tx_data *tx)
182 183 184
{
	struct sk_buff *skb = tx->skb;

185
	ieee80211_tx_set_protected(tx);
186

J
Johannes Berg 已提交
187 188 189 190
	do {
		if (tkip_encrypt_skb(tx, skb) < 0)
			return TX_DROP;
	} while ((skb = skb->next));
191

192
	return TX_CONTINUE;
193 194 195
}


196
ieee80211_rx_result
197
ieee80211_crypto_tkip_decrypt(struct ieee80211_rx_data *rx)
198 199
{
	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data;
200
	int hdrlen, res, hwaccel = 0;
201 202
	struct ieee80211_key *key = rx->key;
	struct sk_buff *skb = rx->skb;
J
Johannes Berg 已提交
203
	struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
204

205
	hdrlen = ieee80211_hdrlen(hdr->frame_control);
206

207
	if (!ieee80211_is_data(hdr->frame_control))
208
		return RX_CONTINUE;
209 210

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

213 214 215 216 217 218
	/*
	 * 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)
219 220 221 222
		hwaccel = 1;

	res = ieee80211_tkip_decrypt_data(rx->local->wep_rx_tfm,
					  key, skb->data + hdrlen,
223
					  skb->len - hdrlen, rx->sta->sta.addr,
224
					  hdr->addr1, hwaccel, rx->queue,
225 226
					  &rx->tkip_iv32,
					  &rx->tkip_iv16);
227
	if (res != TKIP_DECRYPT_OK)
J
Johannes Berg 已提交
228
		return RX_DROP_UNUSABLE;
229 230 231 232 233 234 235 236

	/* Trim ICV */
	skb_trim(skb, skb->len - TKIP_ICV_LEN);

	/* Remove IV */
	memmove(skb->data + TKIP_IV_LEN, skb->data, hdrlen);
	skb_pull(skb, TKIP_IV_LEN);

237
	return RX_CONTINUE;
238 239 240
}


241
static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *scratch,
242 243
				int encrypted)
{
244
	__le16 mask_fc;
245
	int a4_included, mgmt;
246
	u8 qos_tid;
247
	u8 *b_0, *aad;
248 249 250
	u16 data_len, len_a;
	unsigned int hdrlen;
	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
251

252 253 254
	b_0 = scratch + 3 * AES_BLOCK_LEN;
	aad = scratch + 4 * AES_BLOCK_LEN;

255
	/*
256
	 * Mask FC: zero subtype b4 b5 b6 (if not mgmt)
257 258
	 * Retry, PwrMgt, MoreData; set Protected
	 */
259
	mgmt = ieee80211_is_mgmt(hdr->frame_control);
260
	mask_fc = hdr->frame_control;
261
	mask_fc &= ~cpu_to_le16(IEEE80211_FCTL_RETRY |
262
				IEEE80211_FCTL_PM | IEEE80211_FCTL_MOREDATA);
263 264
	if (!mgmt)
		mask_fc &= ~cpu_to_le16(0x0070);
265 266 267 268 269
	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);
270

271 272 273 274 275 276 277 278 279 280
	if (ieee80211_is_data_qos(hdr->frame_control))
		qos_tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK;
	else
		qos_tid = 0;

	data_len = skb->len - hdrlen - CCMP_HDR_LEN;
	if (encrypted)
		data_len -= CCMP_MIC_LEN;

	/* First block, b_0 */
281
	b_0[0] = 0x59; /* flags: Adata: 1, M: 011, L: 001 */
282 283 284 285
	/* Nonce: Nonce Flags | A2 | PN
	 * Nonce Flags: Priority (b0..b3) | Management (b4) | Reserved (b5..b7)
	 */
	b_0[1] = qos_tid | (mgmt << 4);
286
	memcpy(&b_0[2], hdr->addr2, ETH_ALEN);
287 288
	memcpy(&b_0[8], pn, CCMP_PN_LEN);
	/* l(m) */
289
	put_unaligned_be16(data_len, &b_0[14]);
290 291 292

	/* AAD (extra authenticate-only data) / masked 802.11 header
	 * FC | A1 | A2 | A3 | SC | [A4] | [QC] */
293 294
	put_unaligned_be16(len_a, &aad[0]);
	put_unaligned(mask_fc, (__le16 *)&aad[2]);
295
	memcpy(&aad[4], &hdr->addr1, 3 * ETH_ALEN);
296 297 298 299

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

301
	if (a4_included) {
302
		memcpy(&aad[24], hdr->addr4, ETH_ALEN);
303
		aad[30] = qos_tid;
304
		aad[31] = 0;
305
	} else {
306
		memset(&aad[24], 0, ETH_ALEN + IEEE80211_QOS_CTL_LEN);
307
		aad[24] = qos_tid;
308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324
	}
}


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 已提交
325
static inline void ccmp_hdr2pn(u8 *pn, u8 *hdr)
326 327 328 329 330 331 332 333 334 335
{
	pn[0] = hdr[7];
	pn[1] = hdr[6];
	pn[2] = hdr[5];
	pn[3] = hdr[4];
	pn[4] = hdr[1];
	pn[5] = hdr[0];
}


336
static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
337 338 339
{
	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
	struct ieee80211_key *key = tx->key;
340
	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
341
	int hdrlen, len, tail;
342
	u8 *pos, *pn;
343 344
	int i;

345 346 347 348 349 350
	if (info->control.hw_key &&
	    !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV)) {
		/*
		 * hwaccel has no need for preallocated room for CCMP
		 * header or MIC fields
		 */
351
		return 0;
352 353
	}

354
	hdrlen = ieee80211_hdrlen(hdr->frame_control);
355 356
	len = skb->len - hdrlen;

357
	if (info->control.hw_key)
358
		tail = 0;
J
Johannes Berg 已提交
359
	else
360 361 362 363 364
		tail = CCMP_MIC_LEN;

	if (WARN_ON(skb_tailroom(skb) < tail ||
		    skb_headroom(skb) < CCMP_HDR_LEN))
		return -1;
365 366 367 368 369 370 371 372 373 374 375 376 377 378 379

	pos = skb_push(skb, CCMP_HDR_LEN);
	memmove(pos, pos + CCMP_HDR_LEN, hdrlen);
	hdr = (struct ieee80211_hdr *) pos;
	pos += hdrlen;

	/* PN = PN + 1 */
	pn = key->u.ccmp.tx_pn;

	for (i = CCMP_PN_LEN - 1; i >= 0; i--) {
		pn[i]++;
		if (pn[i])
			break;
	}

380
	ccmp_pn2hdr(pos, pn, key->conf.keyidx);
381

382 383
	/* hwaccel - with software CCMP header */
	if (info->control.hw_key)
384 385 386
		return 0;

	pos += CCMP_HDR_LEN;
387 388
	ccmp_special_blocks(skb, pn, key->u.ccmp.tx_crypto_buf, 0);
	ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, key->u.ccmp.tx_crypto_buf, pos, len,
389 390 391 392 393 394
				  pos, skb_put(skb, CCMP_MIC_LEN));

	return 0;
}


395
ieee80211_tx_result
396
ieee80211_crypto_ccmp_encrypt(struct ieee80211_tx_data *tx)
397 398 399
{
	struct sk_buff *skb = tx->skb;

400
	ieee80211_tx_set_protected(tx);
401

J
Johannes Berg 已提交
402 403 404 405
	do {
		if (ccmp_encrypt_skb(tx, skb) < 0)
			return TX_DROP;
	} while ((skb = skb->next));
406

407
	return TX_CONTINUE;
408 409 410
}


411
ieee80211_rx_result
412
ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx)
413
{
414
	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data;
415 416 417
	int hdrlen;
	struct ieee80211_key *key = rx->key;
	struct sk_buff *skb = rx->skb;
J
Johannes Berg 已提交
418
	struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
419 420
	u8 pn[CCMP_PN_LEN];
	int data_len;
421
	int queue;
422

423
	hdrlen = ieee80211_hdrlen(hdr->frame_control);
424

425 426
	if (!ieee80211_is_data(hdr->frame_control) &&
	    !ieee80211_is_robust_mgmt_frame(hdr))
427
		return RX_CONTINUE;
428 429 430

	data_len = skb->len - hdrlen - CCMP_HDR_LEN - CCMP_MIC_LEN;
	if (!rx->sta || data_len < 0)
J
Johannes Berg 已提交
431
		return RX_DROP_UNUSABLE;
432

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

435 436 437 438
	queue = ieee80211_is_mgmt(hdr->frame_control) ?
		NUM_RX_DATA_QUEUES : rx->queue;

	if (memcmp(pn, key->u.ccmp.rx_pn[queue], CCMP_PN_LEN) <= 0) {
439
		key->u.ccmp.replays++;
J
Johannes Berg 已提交
440
		return RX_DROP_UNUSABLE;
441 442
	}

J
Johannes Berg 已提交
443
	if (!(status->flag & RX_FLAG_DECRYPTED)) {
444
		/* hardware didn't decrypt/verify MIC */
445
		ccmp_special_blocks(skb, pn, key->u.ccmp.rx_crypto_buf, 1);
446 447

		if (ieee80211_aes_ccm_decrypt(
448
			    key->u.ccmp.tfm, key->u.ccmp.rx_crypto_buf,
449 450
			    skb->data + hdrlen + CCMP_HDR_LEN, data_len,
			    skb->data + skb->len - CCMP_MIC_LEN,
J
Johannes Berg 已提交
451
			    skb->data + hdrlen + CCMP_HDR_LEN))
J
Johannes Berg 已提交
452
			return RX_DROP_UNUSABLE;
453 454
	}

455
	memcpy(key->u.ccmp.rx_pn[queue], pn, CCMP_PN_LEN);
456 457 458 459 460 461

	/* Remove CCMP header and MIC */
	skb_trim(skb, skb->len - CCMP_MIC_LEN);
	memmove(skb->data + CCMP_HDR_LEN, skb->data, hdrlen);
	skb_pull(skb, CCMP_HDR_LEN);

462
	return RX_CONTINUE;
463
}
464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499


static void bip_aad(struct sk_buff *skb, u8 *aad)
{
	/* BIP AAD: FC(masked) || A1 || A2 || A3 */

	/* FC type/subtype */
	aad[0] = skb->data[0];
	/* Mask FC Retry, PwrMgt, MoreData flags to zero */
	aad[1] = skb->data[1] & ~(BIT(4) | BIT(5) | BIT(6));
	/* A1 || A2 || A3 */
	memcpy(aad + 2, skb->data + 4, 3 * ETH_ALEN);
}


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)
{
	struct sk_buff *skb = tx->skb;
	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
	struct ieee80211_key *key = tx->key;
	struct ieee80211_mmie *mmie;
	u8 *pn, aad[20];
	int i;

500
	if (info->control.hw_key)
501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536
		return 0;

	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 */
	pn = key->u.aes_cmac.tx_pn;

	for (i = sizeof(key->u.aes_cmac.tx_pn) - 1; i >= 0; i--) {
		pn[i]++;
		if (pn[i])
			break;
	}
	bip_ipn_swap(mmie->sequence_number, pn);

	bip_aad(skb, aad);

	/*
	 * MIC = AES-128-CMAC(IGTK, AAD || Management Frame Body || MMIE, 64)
	 */
	ieee80211_aes_cmac(key->u.aes_cmac.tfm, key->u.aes_cmac.tx_crypto_buf,
			   aad, skb->data + 24, skb->len - 24, mmie->mic);

	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 已提交
537
	struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561
	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;

	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 已提交
562
	if (!(status->flag & RX_FLAG_DECRYPTED)) {
563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580
		/* hardware didn't decrypt/verify MIC */
		bip_aad(skb, aad);
		ieee80211_aes_cmac(key->u.aes_cmac.tfm,
				   key->u.aes_cmac.rx_crypto_buf, aad,
				   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;
}