This repository has been archived by the owner on Aug 27, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
mac80211: 802.11w - Add BIP (AES-128-CMAC)
Implement Broadcast/Multicast Integrity Protocol for management frame protection. This patch adds the needed definitions for the new information element (MMIE) and implementation for the new "encryption" type (though, BIP is actually not encrypting data, it provides only integrity protection). These routines will be used by a follow-on patch that enables BIP for multicast/broadcast robust management frames. Signed-off-by: Jouni Malinen <j@w1.fi> Acked-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
- Loading branch information
Showing
8 changed files
with
306 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,6 +15,7 @@ mac80211-y := \ | |
michael.o \ | ||
tkip.o \ | ||
aes_ccm.o \ | ||
aes_cmac.o \ | ||
cfg.o \ | ||
rx.o \ | ||
spectmgmt.o \ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
/* | ||
* AES-128-CMAC with TLen 16 for IEEE 802.11w BIP | ||
* Copyright 2008, Jouni Malinen <j@w1.fi> | ||
* | ||
* 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/kernel.h> | ||
#include <linux/types.h> | ||
#include <linux/crypto.h> | ||
#include <linux/err.h> | ||
|
||
#include <net/mac80211.h> | ||
#include "key.h" | ||
#include "aes_cmac.h" | ||
|
||
#define AES_BLOCK_SIZE 16 | ||
#define AES_CMAC_KEY_LEN 16 | ||
#define CMAC_TLEN 8 /* CMAC TLen = 64 bits (8 octets) */ | ||
#define AAD_LEN 20 | ||
|
||
|
||
static void gf_mulx(u8 *pad) | ||
{ | ||
int i, carry; | ||
|
||
carry = pad[0] & 0x80; | ||
for (i = 0; i < AES_BLOCK_SIZE - 1; i++) | ||
pad[i] = (pad[i] << 1) | (pad[i + 1] >> 7); | ||
pad[AES_BLOCK_SIZE - 1] <<= 1; | ||
if (carry) | ||
pad[AES_BLOCK_SIZE - 1] ^= 0x87; | ||
} | ||
|
||
|
||
static void aes_128_cmac_vector(struct crypto_cipher *tfm, u8 *scratch, | ||
size_t num_elem, | ||
const u8 *addr[], const size_t *len, u8 *mac) | ||
{ | ||
u8 *cbc, *pad; | ||
const u8 *pos, *end; | ||
size_t i, e, left, total_len; | ||
|
||
cbc = scratch; | ||
pad = scratch + AES_BLOCK_SIZE; | ||
|
||
memset(cbc, 0, AES_BLOCK_SIZE); | ||
|
||
total_len = 0; | ||
for (e = 0; e < num_elem; e++) | ||
total_len += len[e]; | ||
left = total_len; | ||
|
||
e = 0; | ||
pos = addr[0]; | ||
end = pos + len[0]; | ||
|
||
while (left >= AES_BLOCK_SIZE) { | ||
for (i = 0; i < AES_BLOCK_SIZE; i++) { | ||
cbc[i] ^= *pos++; | ||
if (pos >= end) { | ||
e++; | ||
pos = addr[e]; | ||
end = pos + len[e]; | ||
} | ||
} | ||
if (left > AES_BLOCK_SIZE) | ||
crypto_cipher_encrypt_one(tfm, cbc, cbc); | ||
left -= AES_BLOCK_SIZE; | ||
} | ||
|
||
memset(pad, 0, AES_BLOCK_SIZE); | ||
crypto_cipher_encrypt_one(tfm, pad, pad); | ||
gf_mulx(pad); | ||
|
||
if (left || total_len == 0) { | ||
for (i = 0; i < left; i++) { | ||
cbc[i] ^= *pos++; | ||
if (pos >= end) { | ||
e++; | ||
pos = addr[e]; | ||
end = pos + len[e]; | ||
} | ||
} | ||
cbc[left] ^= 0x80; | ||
gf_mulx(pad); | ||
} | ||
|
||
for (i = 0; i < AES_BLOCK_SIZE; i++) | ||
pad[i] ^= cbc[i]; | ||
crypto_cipher_encrypt_one(tfm, pad, pad); | ||
memcpy(mac, pad, CMAC_TLEN); | ||
} | ||
|
||
|
||
void ieee80211_aes_cmac(struct crypto_cipher *tfm, u8 *scratch, const u8 *aad, | ||
const u8 *data, size_t data_len, u8 *mic) | ||
{ | ||
const u8 *addr[3]; | ||
size_t len[3]; | ||
u8 zero[CMAC_TLEN]; | ||
|
||
memset(zero, 0, CMAC_TLEN); | ||
addr[0] = aad; | ||
len[0] = AAD_LEN; | ||
addr[1] = data; | ||
len[1] = data_len - CMAC_TLEN; | ||
addr[2] = zero; | ||
len[2] = CMAC_TLEN; | ||
|
||
aes_128_cmac_vector(tfm, scratch, 3, addr, len, mic); | ||
} | ||
|
||
|
||
struct crypto_cipher * ieee80211_aes_cmac_key_setup(const u8 key[]) | ||
{ | ||
struct crypto_cipher *tfm; | ||
|
||
tfm = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC); | ||
if (IS_ERR(tfm)) | ||
return NULL; | ||
|
||
crypto_cipher_setkey(tfm, key, AES_CMAC_KEY_LEN); | ||
|
||
return tfm; | ||
} | ||
|
||
|
||
void ieee80211_aes_cmac_key_free(struct crypto_cipher *tfm) | ||
{ | ||
if (tfm) | ||
crypto_free_cipher(tfm); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
/* | ||
* Copyright 2008, Jouni Malinen <j@w1.fi> | ||
* | ||
* 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. | ||
*/ | ||
|
||
#ifndef AES_CMAC_H | ||
#define AES_CMAC_H | ||
|
||
#include <linux/crypto.h> | ||
|
||
struct crypto_cipher * ieee80211_aes_cmac_key_setup(const u8 key[]); | ||
void ieee80211_aes_cmac(struct crypto_cipher *tfm, u8 *scratch, const u8 *aad, | ||
const u8 *data, size_t data_len, u8 *mic); | ||
void ieee80211_aes_cmac_key_free(struct crypto_cipher *tfm); | ||
|
||
#endif /* AES_CMAC_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters