72 lines
1.8 KiB
C
72 lines
1.8 KiB
C
|
/*
|
||
|
* Software WAPI encryption implementation
|
||
|
* Copyright (c) 2011, XRadioTech
|
||
|
* Author: Janusz Dziedzic <janusz.dziedzic@tieto.com>
|
||
|
*
|
||
|
* 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/random.h>
|
||
|
#include <linux/compiler.h>
|
||
|
#include <linux/crc32.h>
|
||
|
#include <linux/crypto.h>
|
||
|
#include <linux/err.h>
|
||
|
#include <linux/mm.h>
|
||
|
#include <linux/scatterlist.h>
|
||
|
#include <linux/slab.h>
|
||
|
#include <asm/unaligned.h>
|
||
|
|
||
|
#include <net/mac80211.h>
|
||
|
#include "ieee80211_i.h"
|
||
|
#include "wapi.h"
|
||
|
|
||
|
|
||
|
static int ieee80211_wapi_decrypt(struct ieee80211_local *local,
|
||
|
struct sk_buff *skb,
|
||
|
struct ieee80211_key *key)
|
||
|
{
|
||
|
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
|
||
|
int hdrlen = ieee80211_hdrlen(hdr->frame_control);
|
||
|
struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
|
||
|
int data_len;
|
||
|
|
||
|
if (!(status->flag & RX_FLAG_DECRYPTED)) {
|
||
|
/* TODO - SMS4 decryption for firmware without
|
||
|
* SMS4 support */
|
||
|
return RX_DROP_UNUSABLE;
|
||
|
}
|
||
|
|
||
|
|
||
|
data_len = skb->len - hdrlen - WAPI_IV_LEN - WAPI_ICV_LEN;
|
||
|
if (data_len < 0)
|
||
|
return RX_DROP_UNUSABLE;
|
||
|
|
||
|
/* Trim ICV */
|
||
|
skb_trim(skb, skb->len - WAPI_ICV_LEN);
|
||
|
|
||
|
/* Remove IV */
|
||
|
memmove(skb->data + WAPI_IV_LEN, skb->data, hdrlen);
|
||
|
skb_pull(skb, WAPI_IV_LEN);
|
||
|
|
||
|
return RX_CONTINUE;
|
||
|
}
|
||
|
|
||
|
ieee80211_rx_result
|
||
|
ieee80211_crypto_wapi_decrypt(struct ieee80211_rx_data *rx)
|
||
|
{
|
||
|
struct sk_buff *skb = rx->skb;
|
||
|
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
|
||
|
|
||
|
if (!ieee80211_is_data(hdr->frame_control))
|
||
|
return RX_CONTINUE;
|
||
|
|
||
|
if (ieee80211_wapi_decrypt(rx->local, rx->skb, rx->key))
|
||
|
return RX_DROP_UNUSABLE;
|
||
|
|
||
|
return RX_CONTINUE;
|
||
|
}
|