Как зашифровать буфер из ядра в user space
От: Аноним  
Дата: 10.11.07 14:08
Оценка:
День добрый, уважаемые гуру! Подскажите пожалуйста, вопрос по архитектуре построения — выносят ли шифровку/дешифровку данных из 0-го кольца в 3й? Мне очень бы хотелось использовать возможности CryptoAPI, только я не представляю такую связку — драйвер отдает некий буфер сервису — тот его шифрует/дешифрует — и отдает обратно в ядро. Это нормально или есть более умные решения?
Re: Как зашифровать буфер из ядра в user space
От: Аноним  
Дата: 10.11.07 19:22
Оценка:
Зависит от требований е продукту в котором драйвер.
Если секьюрити от возможных троянов и юзеров которые имеют доступ к компу — однозначно не стоит.
Если нужна максимальная производительность — тоже нельзя.
Если же нужно зашифровать трафик письма которое юзер тока что натайпал в the bat и посылаемое по SMTP — почему бы и нет?
А вообще вроде в ядро умудрялись запихивать куски openssl.
Re: Как зашифровать буфер из ядра в user space
От: _cb_  
Дата: 10.11.07 19:49
Оценка:
я портировал вот эту хрень:

http://libtom.org/?page=download&newsitems=5&whatfile=crypt

версию 1.02 (с последней версией гемора больше — автор переделал структуру проекта — появились перекрестные связи с другими проектами)...

портация заняла несколько часов...
только эта штука стек очень любит.... так что работу с ней вытащил в отдельный поток...
Re: Как зашифровать буфер из ядра в user space
От: Аноним  
Дата: 11.11.07 06:48
Оценка:
Да, действительно забыл указать область применения. Шифровка/дешифровка нужна для файла, на который маппится виртуальный том. Соответственно мне приходят (или я должен отдать) данные, выровненные на границе сектора, ну и длинной кратной этому самому сектору. Размер файла может быть очень большим, буфер следовательно тоже, поэтому гонять его туда сюда не очень хочется.
Разбирая EFS пришел к выводу, что там только FEK дешифруется в User space через CryptoAPI, остальная работа производится в ядре. Получается копипастный код? Кусок API реализован и в ядре?
Re[2]: Как зашифровать буфер из ядра в user space
От: Аноним  
Дата: 11.11.07 12:43
Оценка:
Все зависит от того, что вам нужно. Если нужно использовать конкретные криптопровайдеры (CryptoPro и тп), делайте шифрование в user mode. Если не нужно, делайте все в драйвере.
A NTFS для шифрования исползует fips.sys, поиск по форуму даст вам больше информации про этот драйвер.
Re[3]: Как зашифровать буфер из ядра в user space
От: Sergey Storozhevykh Россия  
Дата: 12.11.07 08:14
Оценка: 1 (1)
Здравствуйте, Аноним, Вы писали:

А>Все зависит от того, что вам нужно. Если нужно использовать конкретные криптопровайдеры (CryptoPro и тп), делайте шифрование в user mode. Если не нужно, делайте все в драйвере.


У CryptoPro есть экспорт-драйвер для этих целей У остальных сертифицированных в России CSP, на тот момент, когда я занимался этим вопросом, ничего подобного не было и тоже приходилось шифровать через user-mode. Правда на другом уровне, у автора как я понял уже disk I/O. Наша же система встраивалась поверх файловой системы.

Кстати в Vista используется уже новая технология CNG, которая позволяет снять все вопросы относительно использования сервисов шифрования в kernel-mode.

CNG supports cryptography in kernel mode. The same APIs are used in both kernel and user mode to fully support the cryptography features. Both SSL/TLS and IPSec operate in kernel mode in addition to boot processes that will be using CNG. Not all CNG functions can be called from kernel mode. The reference topic for the functions that cannot be called from kernel mode will explicitly state that the function cannot be called from kernel mode. Otherwise, all CNG functions can be called from kernel mode if the caller is running at PASSIVE_LEVEL IRQL.

Re: Как зашифровать буфер из ядра в user space
От: Аноним  
Дата: 12.11.07 08:23
Оценка:
А если попробовать LPC ?
Re[2]: Как зашифровать буфер из ядра в user space
От: Sergey Storozhevykh Россия  
Дата: 12.11.07 08:59
Оценка: 1 (1)
Здравствуйте, Аноним, Вы писали:

А>А если попробовать LPC ?


Не советую. Это, действительно, проще в части реализации, но с использованием той же inverted call model вы получите гораздо больше бонусов, например, возможность использования completion ports для организации высокопроизводительного сервера и эффективной мультипоточночной модели обработки запросов на шифрование.
Re[4]: Как зашифровать буфер из ядра в user space
От: Аноним  
Дата: 12.11.07 10:52
Оценка:
Здравствуйте, Sergey Storozhevykh, Вы писали:

SS>У CryptoPro есть экспорт-драйвер для этих целей У остальных сертифицированных в России CSP, на тот момент, когда я занимался этим вопросом, ничего подобного не было и тоже приходилось шифровать через user-mode. Правда на другом уровне, у автора как я понял уже disk I/O. Наша же система встраивалась поверх файловой системы.

У большей части сертифицированных библиотек драйверов нет, поэтому лучше, наверное, сделать все в user mode, тем более что в случае с виртуальными дисками это можно сделать без особых потерь по производительности. А то как обычно бывает — сегодня надо использовать CryptoPro, а завтра — еще какую-нибудь криптоэкзотику
Re[3]: Как зашифровать буфер из ядра в user space
От: Аноним  
Дата: 12.11.07 20:26
Оценка:
Здравствуйте, Sergey Storozhevykh, Вы писали:

SS>Здравствуйте, Аноним, Вы писали:


А>>А если попробовать LPC ?


SS>Не советую. Это, действительно, проще в части реализации, но с использованием той же inverted call model вы получите гораздо больше бонусов, например, возможность использования completion ports для организации высокопроизводительного сервера и эффективной мультипоточночной модели обработки запросов на шифрование.


А могли бы ткнуть на пример реализации? От чего можно отталкиваться?
Re[4]: Как зашифровать буфер из ядра в user space
От: Sergey Storozhevykh Россия  
Дата: 13.11.07 07:49
Оценка:
Здравствуйте, Аноним, Вы писали:

А>А могли бы ткнуть на пример реализации? От чего можно отталкиваться?


Kernel: Calling User Mode — Using the Inverted Call Model. Только учтите что у себя нужно будет сделать cancel-safe очереди IRP-запросов. См. Flow of Control for Cancel-Safe IRP Queuing. Также для передачи данных между user/kernel-mode предпочтительно использовать либо direct I/O, либо neither I/O вместо buffered I/O.

По поводу I/O Completion Ports есть информация в MSDN и у Руссиновича, для примера можно посмотреть scanner в WDK.
Re[5]: Как зашифровать буфер из ядра в user space
От: Аноним  
Дата: 13.11.07 12:02
Оценка:
Здравствуйте, Sergey Storozhevykh, Вы писали:

SS>Здравствуйте, Аноним, Вы писали:


А>>А могли бы ткнуть на пример реализации? От чего можно отталкиваться?


SS>Kernel: Calling User Mode — Using the Inverted Call Model. Только учтите что у себя нужно будет сделать cancel-safe очереди IRP-запросов. См. Flow of Control for Cancel-Safe IRP Queuing. Также для передачи данных между user/kernel-mode предпочтительно использовать либо direct I/O, либо neither I/O вместо buffered I/O.


Решил остановиться на direct I/O. Вопрос по Inverted Call Model может я чего-то не так понял, так ли этот механизм следует применять:
1. Сервис с помощью DeviceIOControl создает и отправляет запрос драйверу IOCTL_ЧТО_БЫ_ТЕБЕ_РАСШИФРОВАТЬ.
2. Драйвер пендит этот IRP себе в очередь
3. При необходимости произвести расшифровку (в моем случае, в Dispatch Read ) создается MDL с буфером для дешифровки (заблокирует же его система если direct io?) — IRP отпускается в user mode
4 Самое интересное — сервис в OutBuffer — получает указатель на область данных для дешифровки. Что мне дальше делать?
Создавать новый запрос IO_ВОТ_ТВОИ_РАСШИФРОВАННЫЕ_ДАННЫЕ? Следовательно выделяя память под новый буфер. А если он несколько МБ?
Ведь как я понял, согласно Inverted Call Model, ответ должен уходить в новом запросе драйверу? Или это не обязательно?

Как реюзать тот же буфер в kernel mode? Похоже я запутался со способами передачи буферов от приложения к драйверу и наоборот.


SS>По поводу I/O Completion Ports есть информация в MSDN и у Руссиновича, для примера можно посмотреть scanner в WDK.


Ну а разборки этого можно отложить до полной устаканки вопроса с Inverted Call.

Спасибо.
Re[6]: Как зашифровать буфер из ядра в user space
От: Sergey Storozhevykh Россия  
Дата: 14.11.07 09:49
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Как реюзать тот же буфер в kernel mode? Похоже я запутался со способами передачи буферов от приложения к драйверу и наоборот.


Если на пальцах, то user-mode клиент передает буфер в kernel-mode, отправляя драйверу запрос_1, а драйвер при необходимости зашифровать/расшифровать данные копирует их в буфер, ассоциированный с запросом_1, и завершает этот запрос.

Клиент получает данные, расшифровывает их прямо там же и отправляет драйверу запрос_2, который драйвер трактует как ответ на запрос_1 и копирует себе результат зашифрования/расшифрования.

Когда у драйвера снова есть данные для зашифрования/расшифрования он копирует их в тот же буфер, ассоциированный с запросом_2 и так по кругу. Так что целые серии запросов могут эксплуатировать один и тот же буфер.

Но это не значит, что буфер должен быть единственным, иначе это будет узкое место. Но этот вопрос лучше решать в связке с выбранной (многопоточной) моделью обработки запросов.

А>Как реюзать тот же буфер в kernel mode? Похоже я запутался со способами передачи буферов от приложения к драйверу и наоборот.


Ну так порисуйте чуть-чуть На бумаге это выглядит не так страшно как в голове.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.