Криптование потока сетевого интерфейса

Вопросы программного кода и архитектуры Linux

Модератор: Olej

kit_D
Писатель
Сообщения: 52
Зарегистрирован: 13 мар 2012, 13:14
Откуда: Харьков
Контактная информация:

Re: Криптование потока сетевого интерфейса

Непрочитанное сообщение kit_D » 19 мар 2012, 18:01

Не совсем понял, а что дает то что они реализованы как модули? Вы имеете ввиду, что можно взять весь mac80211 перекомпилить с моими правками? Вариант конечно, но вот если бы mac80211 не был статически прилинкован :-(

kit_D
Писатель
Сообщения: 52
Зарегистрирован: 13 мар 2012, 13:14
Откуда: Харьков
Контактная информация:

Re: Криптование потока сетевого интерфейса

Непрочитанное сообщение kit_D » 19 мар 2012, 18:11

Или вы их подменить хотите?
Смысл в том, что AP (точка доступа), говорит о том что сеть открытая и без шифрования - это для того чтобы существующие сетевые карты и их фирмваре не производила никакого шифрования. Стандартным образом (wpa_supplicant) мы подключаемся к такой открытой сети. После того как мы подключились к AP то мы с ней передоговариваемся об алгоритме шифрования (AP особая и поддерживает такую фичу). Вот после этого наш крипто код и должен срабатывать. Мы криптуем трафик (MPDU фрагменты) на лету и посылаем их в открытую нешифрованную сеть. Фреймы не модифицируются фирмваром - сеть то без криптования.

kit_D
Писатель
Сообщения: 52
Зарегистрирован: 13 мар 2012, 13:14
Откуда: Харьков
Контактная информация:

Re: Криптование потока сетевого интерфейса

Непрочитанное сообщение kit_D » 20 мар 2012, 14:04

Пообщался с разработчиками с linux-wireless. Узнал много нового про WiFi в линукс. Лог прикрепил.
Вложения
linux-wireless.tar
(20 КБ) 411 скачиваний

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: Криптование потока сетевого интерфейса

Непрочитанное сообщение Olej » 20 мар 2012, 14:39

kit_D писал(а):Пообщался с разработчиками с linux-wireless.
А это кто?

kit_D
Писатель
Сообщения: 52
Зарегистрирован: 13 мар 2012, 13:14
Откуда: Харьков
Контактная информация:

Re: Криптование потока сетевого интерфейса

Непрочитанное сообщение kit_D » 20 мар 2012, 14:41

http://linuxwireless.org/ - разработчики mac80211 в линуксе

kit_D
Писатель
Сообщения: 52
Зарегистрирован: 13 мар 2012, 13:14
Откуда: Харьков
Контактная информация:

Re: Криптование потока сетевого интерфейса

Непрочитанное сообщение kit_D » 22 мар 2012, 13:29

Изучив еще раз требования, выяснилось (век живи - век учись) что шифровать-дешифровать надо на уровне 802.11 MPDU фрагментов. Как и в стандартном WPA шифрование должно производиться на уровне MPDU. При этом каждое MPDU содержит MAC header, Frame Data и FCS (контрольную сумму). В WAP шифрование производится по CCMP протоколу в основе которого лежит AES CCM. Работает приблизительно так. НА входе имеем заранее договоренные ключи, некоторый счетчик (вроде как) и сам MPDU. В шифровании берут участие ключи, некоторые данные из MAC header и сам Frame Data. Все это описано в IEEE802.11-2007 для CCMP шифрования (8.3.3.3 CCMP cryptographic encapsulation). В моем же случае "нативного" CCMP шифрования не происходит, так как как сеть объявлена как открытая и без шифрования, но в эту открытую сеть и надо внедрить шифрование аналогичное вышеизложенному. Т.е. точно также шифровать на основании перечислительных выше полей на другим алгоритмом (точнее тем же AES, но в другом режиме).
Исходя из вышесказанного становится понятно, что шифрование skb, которые мы имеем в очередях net_device (и то что видим в Wireshark) не годится Нет там 802.11 MAC header, там он уже преобразован в 802.3 MAC header вид (см. __ieee80211_data_to_8023()). Следовательно, надо опускаться ниже, т.е. на уровень mac80211 фреймворка.

В этом фреймворке "серцевиной" обработки входящих и исходящих пакетов являются следующие функции:
ieee80211_rx_handlers(): http://lxr.free-electrons.com/source/ne ... rx.c#L2664
invoke_tx_handlers: http://lxr.free-electrons.com/source/ne ... tx.c#L1303

На этом уровне работа идет именно с 802.11 MPDU и именно там еще присутствуют 80211 MAC заголовки в чистом виде.
Продолжение следует...

bose
Писатель
Сообщения: 107
Зарегистрирован: 23 фев 2012, 14:41
Откуда: Киев
Контактная информация:

Re: Криптование потока сетевого интерфейса

Непрочитанное сообщение bose » 23 мар 2012, 23:07

kit_D писал(а):В моем же случае "нативного" CCMP шифрования не происходит, так как как сеть объявлена как открытая и без шифрования, но в эту открытую сеть и надо внедрить шифрование аналогичное вышеизложенному. Т.е. точно также шифровать на основании перечислительных выше полей на другим алгоритмом (точнее тем же AES, но в другом режиме).
Исходя из вышесказанного становится понятно, что шифрование skb, которые мы имеем в очередях net_device (и то что видим в Wireshark) не годится Нет там 802.11 MAC header, там он уже преобразован в 802.3 MAC header вид (см. __ieee80211_data_to_8023()). Следовательно, надо опускаться ниже, т.е. на уровень mac80211 фреймворка.

В этом фреймворке "серцевиной" обработки входящих и исходящих пакетов являются следующие функции:
ieee80211_rx_handlers(): http://lxr.free-electrons.com/source/ne ... rx.c#L2664
invoke_tx_handlers: http://lxr.free-electrons.com/source/ne ... tx.c#L1303

На этом уровне работа идет именно с 802.11 MPDU и именно там еще присутствуют 80211 MAC заголовки в чистом виде.
Продолжение следует...
Мне кажется формулировка задачи звучит несколько по-другому - нужно внедрить ещё один алгоритм шифровния (наряду с существующими). Для этого в ядре должен существовать API. Что то типа Cryptographic Service Providers (http://docs.oracle.com/javase/1.4.2/doc ... oviderArch, http://ru.wikipedia.org/wiki/%D0%9A%D1% ... 0%B5%D1%80). Суть - существует ряд стандартных алгоритмов, всяк кто хочет расширить своей "экзотикой" - реализует свои алгоритмы, оборачивает их заданными интерфейсами и регистрирует их в криптомэнэджере. Потом просто выбирается нужный провайдер и указывается Cipher suite (http://en.wikipedia.org/wiki/Cipher_suite), которым нужно пользоваться - всё остальное делается автоматически.

Накопал пару мест в ядре, где есть подобный функционал:
http://lxr.free-electrons.com/source/in ... lib80211.h

Код: Выделить всё

struct lib80211_crypto_ops {
/* encrypt/decrypt return < 0 on error or >= 0 on success. The return
          * value from decrypt_mpdu is passed as the keyidx value for
          * decrypt_msdu. skb must have enough head and tail room for the
          * encryption; if not, error will be returned; these functions are
          * called for all MPDUs (i.e., fragments).
          */
         int (*encrypt_mpdu) (struct sk_buff * skb, int hdr_len, void *priv);
         int (*decrypt_mpdu) (struct sk_buff * skb, int hdr_len, void *priv);
 
         /* These functions are called for full MSDUs, i.e. full frames.
          * These can be NULL if full MSDU operations are not needed. */
         int (*encrypt_msdu) (struct sk_buff * skb, int hdr_len, void *priv);
         int (*decrypt_msdu) (struct sk_buff * skb, int keyidx, int hdr_len,
                              void *priv);
}; 
struct lib80211_crypt_data {
};
struct lib80211_crypt_info {
};
int lib80211_crypt_info_init(struct lib80211_crypt_info *info, char *name, spinlock_t *lock);
void lib80211_crypt_info_free(struct lib80211_crypt_info *info);
int lib80211_register_crypto_ops(struct lib80211_crypto_ops *ops);
int lib80211_unregister_crypto_ops(struct lib80211_crypto_ops *ops);
struct lib80211_crypto_ops *lib80211_get_crypto_ops(const char *name);
Ну а вот здесь всё это реализовано (как варианты):
http://lxr.free-electrons.com/source/ne ... ypt_ccmp.c
http://lxr.free-electrons.com/source/ne ... rypt_wep.c
http://lxr.free-electrons.com/source/ne ... ypt_tkip.c

Код в этом месте плохо задокументирован, но может стоит с этой стороны подойти к вопросу?

kit_D
Писатель
Сообщения: 52
Зарегистрирован: 13 мар 2012, 13:14
Откуда: Харьков
Контактная информация:

Re: Криптование потока сетевого интерфейса

Непрочитанное сообщение kit_D » 26 мар 2012, 16:21

Мда, странные функции - они не вызываются из mac80211. Похоже что они используются драйверами не совместимыми с mac80211 фреймворком.

kit_D
Писатель
Сообщения: 52
Зарегистрирован: 13 мар 2012, 13:14
Откуда: Харьков
Контактная информация:

Re: Криптование потока сетевого интерфейса

Непрочитанное сообщение kit_D » 27 мар 2012, 12:52

В этом фреймворке "серцевиной" обработки входящих и исходящих пакетов являются следующие функции:
ieee80211_rx_handlers(): http://lxr.free-electrons.com/source/ne ... rx.c#L2664
invoke_tx_handlers: http://lxr.free-electrons.com/source/ne ... tx.c#L1303

На этом уровне работа идет именно с 802.11 MPDU и именно там еще присутствуют 80211 MAC заголовки в чистом виде.
Продолжение следует...
Выясняются новые подробности. Нет необходимости доступаться до 802.11 MPDU уровня. На самом деле 802.11 фреймы, на выходе из mac802.11 конвернируются в 802.3 фреймы. И вот именно их и надо шифровать. Для этого, в моем модуле надо уметь подцепиться к заданному сетевому интерфейсу и перехватывать все входящие и исходящие 802.3 фреймы. Задача - зашифровать(AES) содержимое фрейма который пришел из сетевого стека перед его выдачей в сеть. И наоборот, полученный из сети фрейм надо расшифровать и отправить вверх в сетевой стек.

Для реализации такого подхода можно использовать следующее:
1) Для ТХ фреймов (исходящих из wlan0) нечто следующее:

static struct net_device_ops *orig_dataif_ops;
static struct net_device_ops new_dataif_ops;
struct net_device *slave;

netdev_tx_t my_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
return orig_start_xmit(skb, dev);
}

int __init crypto_init(void)
{
...
...
/* Запоминаем net_device_ops структуру зарегистрированную для wlan0 и заменяем ее на новую, */
/* с подмененной ndo_start_xmit колбека на наш my_start_xmit()*/
slave = __dev_get_by_name(&init_net, slave_name);
if (slave && slave->netdev_ops)
{
/* save original net_device options*/
orig_dataif_ops = slave->netdev_ops;
new_dataif_ops = *slave->netdev_ops;

/* update ndo_start_xmit */
orig_start_xmit = slave->netdev_ops->ndo_start_xmit;

/* change net_device to new ones */
new_dataif_ops.ndo_start_xmit = my_start_xmit;

slave->netdev_ops = &new_dataif_ops;
}
}

2) Для RX фреймов (входящих в wlan0) используем netdev_rx_handler_register:
struct net_device *slave;

rx_handler_result_t handle_frame(struct sk_buff **pskb)
{
struct sk_buff *skb = *pskb;

/* printk(KERN_WARNING "%s: Address src=%pM dst=%pM len=%d data_len=%d mac_len=%d\n", skb->dev->name, eth_hdr(skb)->h_source, eth_hdr(skb)->h_dest, skb->len, skb->data_len, skb->mac_len); */
#if 1
/* We need to remove scb from slave device and push it to crypto device */
if (crypto_dev)
{
struct crypto_priv *priv = netdev_priv(crypto_dev);

priv->priv_stats.rx_packets++;
priv->priv_stats.rx_bytes += skb->len;

printk("injecting frame from %s to %s\n", skb->dev->name, crypto_dev->name);
skb->dev = crypto_dev;
return RX_HANDLER_ANOTHER;
}
#endif
return RX_HANDLER_PASS;
}


int __init crypto_init(void)
{
...
...
slave = __dev_get_by_name(&init_net, slave_name);
if (!slave)
return -ENODEV;

netdev_rx_handler_register(slave, handle_frame, NULL);
...
...
}

Note: тут еще проблемка. netdev_rx_handler_register() относительно новый хук и появился он в 2.6.36, а мне надо чтобы модуль был также совместим с 2.6.35. Наверняка там есть какой-то аналог этой функции - надо копать
Последний раз редактировалось kit_D 27 мар 2012, 13:01, всего редактировалось 1 раз.

kit_D
Писатель
Сообщения: 52
Зарегистрирован: 13 мар 2012, 13:14
Откуда: Харьков
Контактная информация:

Re: Криптование потока сетевого интерфейса

Непрочитанное сообщение kit_D » 27 мар 2012, 12:58

Кроме того, чтобы отслеживать события на интерфейсе wlan0 (изменение статуса и т.п.) вероятно надо будет дополнительно отслеживать event notifiers. Нечто вроде:

static struct notifier_block my_notifier = {
.notifier_call = handle_netdev_event,
};

static int
handle_netdev_event(struct notifier_block *self, unsigned long event, void *val)
{
struct net_device *dev = NULL;

switch (event)
{
case NETDEV_REGISTER:
...
break;
case NETDEV_UNREGISTER:
...
break;
default:
break;
}

return 0;
}


static int __init _mod_init(void)
{
...
register_netdevice_notifier(&my_notifier);
...
}

Ответить

Вернуться в «Linux изнутри»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 9 гостей