43#include <sys/malloc.h>
44#include <sys/kernel.h>
45#include <sys/module.h>
47#include <sys/socket.h>
50#include <net/if_media.h>
51#include <net/ethernet.h>
55#include <crypto/rijndael/rijndael.h>
57#define AES_BLOCK_LEN 16
93 struct mbuf *,
int hdrlen);
121 KASSERT(
nrefs > 0, (
"imbalanced attach/detach"));
132 "%s: Invalid key length %u, expecting %u\n",
195 ivp = mtod(m, uint8_t *);
221static __inline uint64_t
222READ_6(uint8_t b0, uint8_t b1, uint8_t b2, uint8_t b3, uint8_t b4, uint8_t b5)
224 uint32_t iv32 = (b0 << 0) | (b1 << 8) | (b2 << 16) | (b3 << 24);
225 uint16_t iv16 = (b4 << 0) | (b5 << 8);
226 return (((uint64_t)iv16) << 32) | iv32;
254 ivp = mtod(m, uint8_t *) + hdrlen;
260 "%s",
"missing ExtIV for AES-CCM cipher");
265 pn =
READ_6(ivp[0], ivp[1], ivp[4], ivp[5], ivp[6], ivp[7]);
266 if (pn <= k->wk_keyrsc[tid] &&
292 ovbcopy(mtod(m,
void *), mtod(m, uint8_t *) +
ccmp.
ic_header,
326 for (i = 0; i < len; i++)
346 u_int64_t pn,
size_t dlen,
350#define IS_QOS_DATA(wh) IEEE80211_QOS_HAS_SEQ(wh)
366 b0[14] = (dlen >> 8) & 0xff;
367 b0[15] = dlen & 0xff;
378 aad[2] = wh->
i_fc[0] & 0x8f;
379 aad[3] = wh->
i_fc[1] & 0xc7;
400 aad[30] = qwh4->
i_qos[0] & 0x0f;
405 *(uint16_t *)&aad[30] = 0;
413 aad[24] = qwh->
i_qos[0] & 0x0f;
418 *(uint16_t *)&aad[24] = 0;
422 *(uint16_t *)&aad[26] = 0;
423 *(uint32_t *)&aad[28] = 0;
427 rijndael_encrypt(ctx, b0, auth);
429 rijndael_encrypt(ctx, auth, auth);
431 rijndael_encrypt(ctx, auth, auth);
434 rijndael_encrypt(ctx, b0, s0);
438#define CCMP_ENCRYPT(_i, _b, _b0, _pos, _e, _len) do { \
440 xor_block(_b, _pos, _len); \
441 rijndael_encrypt(&ctx->cc_aes, _b, _b); \
443 _b0[14] = (_i >> 8) & 0xff; \
444 _b0[15] = _i & 0xff; \
445 rijndael_encrypt(&ctx->cc_aes, _b0, _e); \
446 xor_block(_pos, _e, _len); \
455 int data_len, i, space;
465 data_len, b0, aad, b, s0);
472 if (space > data_len)
514 pos_next = mtod(n, uint8_t *);
516 space_next = len > sp ? len - sp : 0;
517 if (n->m_len >= space_next) {
531 sp += n->m_len, dl -= n->m_len;
543 pos_next = mtod(m, uint8_t *);
545 space_next = len > sp ? len - sp : 0;
546 if (m->m_len >= space_next) {
551 sp += m->m_len, dl -= m->m_len;
566 pos = pos_next + space_next;
567 space = m->m_len - space_next;
572 pos = mtod(m, uint8_t *);
583#define CCMP_DECRYPT(_i, _b, _b0, _pos, _a, _len) do { \
585 _b0[14] = (_i >> 8) & 0xff; \
586 _b0[15] = _i & 0xff; \
587 rijndael_encrypt(&ctx->cc_aes, _b0, _b); \
588 xor_block(_pos, _b, _len); \
590 xor_block(_a, _pos, _len); \
591 rijndael_encrypt(&ctx->cc_aes, _a, _a); \
620 if (space > data_len)
647 pos_next = mtod(m, uint8_t *);
649 space_next = len > space ? len - space : 0;
650 KASSERT(m->m_len >= space_next,
651 (
"not enough data in following buffer, "
652 "m_len %u need %u\n", m->m_len, space_next));
654 xor_block(b+space, pos_next, space_next);
656 xor_block(pos_next, b+space, space_next);
660 pos = pos_next + space_next;
661 space = m->m_len - space_next;
666 pos = mtod(m, uint8_t *);
672 "%s",
"AES-CCM decrypt failed; MIC mismatch");
#define IEEE80211_RX_F_IV_STRIP
#define IEEE80211_RX_F_MMIC_STRIP
#define IEEE80211_IS_MGMT(wh)
#define IEEE80211_WEP_KIDLEN
#define IEEE80211_WEP_IVLEN
#define IEEE80211_ADDR_LEN
#define IEEE80211_WEP_MICLEN
#define IEEE80211_SEQ_FRAG_MASK
#define IEEE80211_IS_DSTODS(wh)
#define IEEE80211_WEP_EXTIVLEN
#define IEEE80211_WEP_EXTIV
uint8_t ieee80211_crypto_get_keyid(struct ieee80211vap *vap, struct ieee80211_key *k)
void ieee80211_notify_replay_failure(struct ieee80211vap *, const struct ieee80211_frame *, const struct ieee80211_key *, uint64_t rsc, int tid)
#define IEEE80211_KEY_NOIVMGT
#define IEEE80211_CIPHER_AES_CCM
#define IEEE80211_KEY_NOIV
#define IEEE80211_KEY_NOREPLAY
#define IEEE80211_KEY_SWDECRYPT
#define IEEE80211_KEY_SWENCRYPT
static __inline void xor_block(uint8_t *b, const uint8_t *a, size_t len)
static int ccmp_decrypt(struct ieee80211_key *, u_int64_t pn, struct mbuf *, int hdrlen)
static void ccmp_setiv(struct ieee80211_key *, uint8_t *)
static const struct ieee80211_cipher ccmp
static int ccmp_decap(struct ieee80211_key *, struct mbuf *, int)
static int ccmp_encap(struct ieee80211_key *, struct mbuf *)
#define CCMP_ENCRYPT(_i, _b, _b0, _pos, _e, _len)
IEEE80211_CRYPTO_MODULE(ccmp, 1)
#define CCMP_DECRYPT(_i, _b, _b0, _pos, _a, _len)
static void ccmp_init_blocks(rijndael_ctx *ctx, struct ieee80211_frame *wh, u_int64_t pn, size_t dlen, uint8_t b0[AES_BLOCK_LEN], uint8_t aad[2 *AES_BLOCK_LEN], uint8_t auth[AES_BLOCK_LEN], uint8_t s0[AES_BLOCK_LEN])
static int ccmp_enmic(struct ieee80211_key *, struct mbuf *, int)
static void ccmp_detach(struct ieee80211_key *)
static __inline uint64_t READ_6(uint8_t b0, uint8_t b1, uint8_t b2, uint8_t b3, uint8_t b4, uint8_t b5)
static int ccmp_demic(struct ieee80211_key *, struct mbuf *, int)
static void * ccmp_attach(struct ieee80211vap *, struct ieee80211_key *)
static int ccmp_encrypt(struct ieee80211_key *, struct mbuf *, int hdrlen)
static int ccmp_setkey(struct ieee80211_key *)
const struct ieee80211_rx_stats * ieee80211_get_rx_params_ptr(struct mbuf *m)
#define IEEE80211_M_NOWAIT
static __inline uint8_t ieee80211_gettid(const struct ieee80211_frame *wh)
#define IEEE80211_ADDR_COPY(dst, src)
static __inline int ieee80211_hdrspace(struct ieee80211com *ic, const void *data)
#define IEEE80211_MSG_CRYPTO
#define IEEE80211_NOTE_MAC(_vap, _m, _mac, _fmt,...)
#define IEEE80211_DPRINTF(_vap, _m, _fmt,...)
struct ieee80211com * cc_ic
struct ieee80211vap * cc_vap
uint8_t i_addr1[IEEE80211_ADDR_LEN]
uint8_t i_addr2[IEEE80211_ADDR_LEN]
uint8_t wk_key[IEEE80211_KEYBUF_SIZE+IEEE80211_MICBUF_SIZE]
uint64_t wk_keyrsc[IEEE80211_TID_SIZE]
uint32_t is_rx_ccmpreplay
uint32_t is_rx_ccmpformat
struct ieee80211com * iv_ic
struct ieee80211_stats iv_stats