CryptoAPI ядра Linux: разработка и применение российской криптографии

imageCryptoAPI представляет собой реализацию криптографических алгоритмов с предоставлением доступа к ним как из самого ядра, так и из прикладного программного обеспечения. Наиболее яркими представителями этого программного обеспечения является IPSEC (VPN ) и dm-crypt (шифрованная файловая система).

Конечной целью данного материала будет создание шифрованной файловой системы с использованием российских криптографических алгоритмов:

  • Выработку значения хэш-функции в соответствии с требованиями ГОСТ Р 34.11-94 / ГОСТ Р 34.11-2012 «Информационная технология. Криптографическая защита информации. Функция хэширования»;
  • Зашифрование/расшифрование данных и вычисление имитовставки в соответствии с требованиями ГОСТ 28147-89 «Системы обработки информации. Защита криптографическая»;
  • Зашифрование/расшифрование данных алгоритмами шифрования «Кузнечик» (КУЗмин, НЕЧаев И Компания) и «Магма» в соответствии с требованиями «ГОСТ Р 34.12-2015 Информационная технология. Криптографическая защита информации. Блочные шифры» и «ГОСТ Р 34.13-2015 Информационная технология. Криптографическая защита информации. Режимы работы блочных шифров».

Посмотреть какие криптографические алгоритмы могут использоваться для создания шифрованной файловой системы можно следующими командами:

bash-4.3$ /usr/local/bin64/cryptsetup benchmark
# Tests are approximate using memory only (no storage IO).
PBKDF2-sha1       620459 iterations per second
PBKDF2-sha256     541619 iterations per second
PBKDF2-sha512     357144 iterations per second
#  Algorithm | Key |  Encryption |  Decryption
     aes-cbc   128b   467,6 MiB/s  1686,1 MiB/s
 serpent-cbc   128b    74,5 MiB/s   264,4 MiB/s
     aes-cbc   256b   350,1 MiB/s  1333,8 MiB/s
 serpent-cbc   256b    74,2 MiB/s   265,3 MiB/s
bash-4.3$ /usr/local/bin64/cryptsetup  benchmark  -caes-ecb
# Tests are approximate using memory only (no storage IO).
#  Algorithm | Key |  Encryption |  Decryption
     aes-ecb   256b  1422,6 MiB/s  1437,6 MiB/s
bash-4.3$

Как видно из данного примера для создания шифрованной файловой системы могут использоваться алгоритм шифрования AES в режимах CBC и ECB, а также хэш функции sha1, sha256 и sha512.

Для перехода на российскую криптографию нам необходимо добавить в ядро Linux модули, реализующие хэш по ГОСТ Р 34.11-94, ГОСТ Р 34.11-2012 с длиной хэша 256 бит (STRIBOG-256) и длиной хэша 512 бит (STRIBOG-512).

В качестве алгоритмов шифрования должны быть реализованы ГОСТ 28147-89, он же фактически алгоритм «Магма» (ГОСТ Р 34.12-2015), а также алгоритм «Кузнечик» (ГОСТ Р 34.12-2015). Для проверки будут задействованы режимы шифрования CBC, ECB.

В качестве прототипов этих модулей рассматриваются модули aes-generic и shaxxx-generic. Соответственно для российской криптографии должны быть реализованы модули:

  • gosthash-generic (ГОСТ К 34.11-94);
  • stribog256-generic (ГОСТ Р 34.11-2012 с длиной хэша 256 бит);
  • stribog512-generic (ГОСТ Р 34.11-2012 с длиной хэша 512 бит);
  • gost-generic (ГОСТ 28147-89, «Магма»);
  • kuznyechik-generic («Кузнечик»).

Главный вопрос – где взять реализацию российских криптографических алгоритмов? Одним из вариантов является OpenSSL и поддержка ГОСТ-ых алгоритмов в engine gost. Однако до настоящего времени так и поддерживается реализация только ГОСТ 28147-89 и ГОСТ Р 34.11-94. Более приемлемым является поддержка российских криптографических алгоритмов в проекте GCrypt-1.7.0, где уже имеется поддержка алгоритм «Магма» (ГОСТ Р 34.12-2015) и ГОСТ Р 34.11-2012 с длиной хэш-а 256 бит (STRIBOG-256) и длиной хэш-а 512 бит (STRIBOG-512).

Что касается «Кузнечика», то здесь поможет статья на Habrahabr«ГОСТ Р 34.12-15 на SSE2, или Не так уж и плох Кузнечик».

Сборка модулей проводилась для следующего ядра Linux:

bash-4.3$ uname -sr
Linux 4.4.39-desktop-1.mga5
bash-4.3$

Для других ядер могут потребоваться какие-то изменения. Сборку модулей CryptoAPI, реализующих российские крипто-алгоритмы, покажем на примере модуля stribog256-generic (ГОСТ Р 34.11-2012 с длиной хэш-аа 256 бит).

Итак, Makefile:

obj-m := stribog256_generic.o
my-objs := stribog.o
KDIR  := /lib/modules/$(shell uname -r)/build
PWD   := $(shell pwd)
default:
	$(MAKE) -C $(KDIR) M=$(PWD) modules
clean:
	$(MAKE) -C $(KDIR) M=$(PWD) clean
install:
	$(MAKE) -C $(KDIR) M=$(PWD) modules_install

Укажем также содержимое каталога stribog256_generic:

bash-4.3$ ls 
rypto_mult_table.h
hash_bit.h
Makefile
stribog256_generic.c
stribog256.h
stribog.c
stribog.h
bash-4.3$	

Для сборки модуля достаточно войти в каталог stribog256 и выполнить команду make:

bash-4.3$ make
make -C /lib/modules/4.4.39-desktop-1.mga5/build M=/home/a513/DM_CRYPT/dm-crypt/stribog256 modules
make[1]: вход в каталог «/usr/src/kernel-4.4.39-desktop-1.mga5»
  CC [M]  /home/a513/DM_CRYPT/dm-crypt/stribog256/stribog256_generic.o
…
  Building modules, stage 2.
  MODPOST 1 modules
  CC      /home/a513/DM_CRYPT/dm-crypt/stribog256/stribog256_generic.mod.o
  LD [M]  /home/a513/DM_CRYPT/dm-crypt/stribog256/stribog256_generic.ko
make[1]: выход из каталога «/usr/src/kernel-4.4.39-desktop-1.mga5»
bash-4.3$ 

Код модуля stribog256_generic.c выглядит следующим образом:

Код модуля stribog256_generic.c выглядит следующим образом:
bash-4.3$ cat stribog256_generic.c 

/
*
 * Cryptographic API.
 *
 * Stribog256 Secure Hash Algorithm.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option)
 * any later version.
 *
 */
#include <linux/init.h>
#include <linux/module.h>
#include <linux/mm.h>
#include <linux/types.h>
#include <crypto/internal/hash.h>
#include "stribog256.h"
#include "stribog.c"
static int stribog256_init(struct shash_desc *desc)
{
        struct stribog_ctx *sctx = shash_desc_ctx(desc);
        GOSTR3411_2012_256_Init(sctx);
        return 0;
}
int crypto_stribog256_update(struct shash_desc *desc, const u8 *data,
                        u32 len)
{
        struct stribog_ctx *sctx = shash_desc_ctx(desc);
        GOSTR3411_2012_Update(sctx, data, len); 
        return 0;
}
EXPORT_SYMBOL(crypto_stribog256_update);
/* Add padding and return the message digest. */
static int stribog256_final(struct shash_desc *desc, u8 *out)
{
        struct stribog_ctx *sctx = shash_desc_ctx(desc);
        GOSTR3411_2012_256_Final(sctx, out);
        // Wipe context 
        memset(sctx, 0, sizeof(*sctx));
        return 0;
}
static int stribog256_export(struct shash_desc *desc, void *out)
{
        struct stribog_ctx *sctx = shash_desc_ctx(desc);
        memcpy(out, sctx, sizeof(*sctx));
        return 0;
}
static int stribog256_import(struct shash_desc *desc, const void *in)
{
        struct stribog_ctx *sctx = shash_desc_ctx(desc);
        memcpy(sctx, in, sizeof(*sctx));
        return 0;
}
static struct shash_alg alg = {
        .digestsize     =       STRIBOG256_DIGEST_SIZE,
        .init           =       stribog256_init,
        .update         =       crypto_stribog256_update,
        .final          =       stribog256_final,
        .export         =       stribog256_export,
        .import         =       stribog256_import,
        .descsize       =       sizeof(struct stribog_ctx),
        .statesize      =       sizeof(struct stribog_ctx),
        .base           =       {
                .cra_name       =       "stribog256",
                .cra_driver_name=       "stribog256-generic",
                .cra_flags      =       CRYPTO_ALG_TYPE_SHASH,
                .cra_blocksize  =       STRIBOG_BLOCK_SIZE,
                .cra_module     =       THIS_MODULE,
        }
};
static int __init stribog256_generic_mod_init(void)
{
        return crypto_register_shash(&alg);
}
static void __exit stribog256_generic_mod_fini(void)
{
        crypto_unregister_shash(&alg);
}
module_init(stribog256_generic_mod_init);
module_exit(stribog256_generic_mod_fini);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Stribog256 Secure Hash Algorithm");
MODULE_ALIAS_CRYPTO("stribog256");
MODULE_ALIAS_CRYPTO("stribog256-generic");

bash-4.3$


По аналогичной схеме готовятся и собираются и остальные модули:

bash-4.3$ ls -C1
gost_generic.ko
gosthash_generic.ko
kuznyechik_generic.ko
stribog256_generic.ko
stribog512_generic.ko
bash-4.3$

Теперь их можно грузить в систему:

bash-4.3#insmod ./ stribog256_generic.ko
bash-4.3#

Теперь посмотрим какие алгоритмы поддерживает CryptoAPI:

bash-4.3$ /usr/local/bin64/cryptsetup benchmark
# Tests are approximate using memory only (no storage IO).
PBKDF2-sha1       679129 iterations per second
PBKDF2-sha256     544431 iterations per second
PBKDF2-sha512     355208 iterations per second
PBKDF2-gosthash   138994 iterations per second
PBKDF2-stribog256  123187 iterations per second
PBKDF2-stribog512   91275 iterations per second
#  Algorithm | Key |  Encryption |  Decryption
     aes-cbc   128b   468,0 MiB/s  1700,7 MiB/s
 serpent-cbc   128b    74,0 MiB/s   266,9 MiB/s
     aes-cbc   256b   349,2 MiB/s  1349,4 MiB/s
 serpent-cbc   256b    72,8 MiB/s   259,1 MiB/s
    gost-cbc   256b    38,3 MiB/s    46,8 MiB/s
kuznyechik-cbc   256b     3,6 MiB/s     3,2 MiB/s
bash-4.3$ 

Для того, чтобы ГОСТ-вые алгоритмы появились при тестировании (параметр benchmark) в утилиту cryptsetup достаточно внести изменения в следующие файлы:

1. ./cryptsetup/src/cryptsetup.c (строки добавлены только для команды тестирования)

static struct {
		const char *cipher;
		const char *mode;
		size_t key_size;
		size_t iv_size;
	} bciphers[] = {
		{ "aes",     "cbc", 16, 16 },
		{ "serpent", "cbc", 16, 16 },
		{ "aes",     "cbc", 32, 16 },
		{ "serpent", "cbc", 32, 16 },
/*ГОСТ*/
		{ "gost", "cbc", 32, 8 },
		{ "gost", "ecb", 32, 8 },
		{ "gost", "crt", 32, 8 },
		{ "kuznyechik", "cbc", 32, 16 },

		{  NULL, NULL, 0, 0 }
	};

2. ./cryptsetup/lib/crypto_backend/crypto_cipher_kernel.c

static struct cipher_alg cipher_algs[] = {
    { "cipher_null", 16 },
    { "aes",         16 },
    { "serpent",     16 },
    { "twofish",     16 },
    { "anubis",      16 },
    { "blowfish",     8 },
    { "camellia",    16 },
    { "cast5",        8 },
    { "cast6",       16 },
    { "des",          8 },
    { "des3_ede",     8 },
    { "khazad",       8 },
    { "seed",        16 },
    { "tea",          8 },
    { "xtea",         8 },
/*ГОСТ*/
    { "gost",         8 },
    { "kuznyechik",         8 },

    { NULL,           0 }
};

3. ./cryptsetup/lib/crypto_backend/crypto_kernel.c

static struct hash_alg hash_algs[] = {
    { "sha1",      "sha1",   20,  64 },
/*ГОСТ*/
    { "gosthash",      "gosthash",   32,  64 },
    { "stribog256",      "stribog256",   32,  128 },
    { "stribog512",      "stribog512",   64,  128 },
    { "sha256",    "sha256", 32,  64 },
    { "sha512",    "sha512", 64, 128 },
    { "ripemd160", "rmd160", 20,  64 },
    { "whirlpool", "wp512",  64,  64 },
    { NULL,        NULL,      0,   0 }
};

Можно эти изменения не вносить, но тогда потребуется тестировать алгоритмы с явным указанием шифра и режима (моды). Более того именно так и только так мы можем проверить ГОСТ-ые шифры в режиме ECB:

bash-4.3$ /usr/local/bin64/cryptsetup benchmark -cgost-ecb
# Tests are approximate using memory only (no storage IO).
#  Algorithm | Key |  Encryption |  Decryption
    gost-ecb   256b    50,4 MiB/s    49,2 MiB/s
bash-4.3$ /usr/local/bin64/cryptsetup  benchmark  -ckuznyechik-ecb
# Tests are approximate using memory only (no storage IO).
#  Algorithm | Key |  Encryption |  Decryption
kuznyechik-ecb   256b     3,4 MiB/s     3,2 MiB/s
bash-4.3$# Tests are approximate using memory only (no storage IO).
bash-4.3$ 
#  Algorithm | Key |  Encryption |  Decryption
     aes-ecb   256b  1361,8 MiB/s  1381,5 MiB/s
bash-4.3$ 

И так с модулями мы разобрались. Теперь можно создавать защищенную файловую систему с шифрованием на ГОСТ-ах. Для начала создадим файл test.bin:

# dd if=/dev/zero of=/tmp/test.bin bs=10M count=50
50+0 записей получено
50+0 записей отправлено
 скопировано 524288000 байт (524 MB), 0,44706 c, 1,2 GB/c
[root@VOrlov_64 tmp]#

Шифрованную файловую систему будем создавать именно в этом файле:

[root@VOrlov_64 tmp]# /usr/local/bin64/cryptsetup - kuznyechik-ecb -h stribog256 -y luksFormat /tmp/test.bin

WARNING!
========
This will overwrite data on /tmp/test.bin irrevocably.

Are you sure? (Type uppercase yes): YES
Enter passphrase: 01234567
Verify passphrase: 01234567
[root@VOrlov_64 tmp]#

Подключение файловой системы:

#cryptsetup luksOpen <устройство/файл> volume1

И так подключаем нашу защищенную ФС к тому volume1:

[root@VOrlov_64 tmp]# /usr/local/bin64/cryptsetup luksOpen /tmp/test.bin volume1
Enter passphrase for /tmp/test.bin: 
[root@VOrlov_64 tmp]#

Далее работаем с устройством /dev/mapper/volume1 как с обычным разделом жесткого диска.

Посмотреть параметры файловой системы:

root@VOrlov_64 tmp]# /usr/local/bin64/cryptsetup status /dev/mapper/volume1
/dev/mapper/volume1 is active.
  type:    LUKS1
  cipher:  kuznyechik-ecb
  keysize: 256 bits
  device:  /dev/loop0
  loop:    /tmp/test.bin
  offset:  4096 sectors
  size:    1019904 sectors
  mode:    read/write
[root@VOrlov_64 tmp]# 

После этого достаточно создать файловую систему (ФС) на устройстве /dev/mapper/volume1:

#mkfs.ext4 /dev/mapper/volume1
#

Монтируем ФС и работаем с ней:

#mount /dev/mapper/volume1 /mount/TEST_DM_CRYPT_GOST
#

Все, теперь мы можем создавать шифрованные ФС на ГОСТ 28147-89 (он же ГОСТ Р 34.12-2015 Магма) и ГОСТ Р 34.12-2015 Кузнечик) в режимах CBC, ECB. В качестве алгоритма хэширование могут использоваться ГОСТ Р 34.11-94), stribog256 (ГОСТ Р 34.11-2012 256 бит) и stribog512 (ГОСТ Р 34.11-2012 512бит).
Поделиться публикацией

Похожие публикации

AdBlock похитил этот баннер, но баннеры не зубы — отрастут

Подробнее
Реклама

Комментарии 28

    0
    Все, теперь мы можем создавать шифрованные ФС

    И нести его на спец. исследования в ФСБ(*) :-)
    Но очень интересно, спасибо.
    *Убедитесь в наличии у вас всех соответствующих лицензий.
      0

      Ну нести это имеет смысл только если будет востребовано. В текущей ситуации и ценами на сертификацию — проводить тематические исследования в инициативном порядке по линии ФСБ просто убыточно.

        0
        А какое отношение спец исследования имеют к защите раздела/диска? И при чем лицензии?
          0
          Ну как же.
          Обычно заморачиваться с ГОСТ для шифрования имеет смысл только там, где это обусловлено требованиями законодательства, ибо в остальных случаях надо использовать AES с аппаратным ускорением, которое позволяет вообще не замечать наличия FDE.
          А там где требования законодательства, там и требования по сертификации полученного результата. Да даже и без этого, осуществление работ связанных с криптографической защитой — уже лицензируемый вид деятельности. Тут только если Топикстартер захочет нам рассказать как ему удается проскочить между этими струйками.
          В редких случаях я слышал «надо чтобы по госту, но сертифицировать не обязательно».
            0
            Чтобы избежать сертификации нужно шифровать не «по ГОСТ-у», а по алгоритму «на базе алгоритма ГОСТ» и обязательно с «малой длиной ключа» (до недавнего времени это было менее 56 бит). Тогда это «поделие» попадает под определение «не подлежащее сертификации». Делается это достаточно просто — в паспорте (или в документе, заменяющем его) делается упоминание, что константная составляющая ключа имеет следующий вид <константная составляющая ключа, например, в шестнадцатиричном представлении>. В «поделии» эта составляющая записывается в виде константы и при выполнении преобразований объединяется с «малой» частью ключа.
              0
              Это понятно, занижение ключа чтобы избежать регулиования — понятный метод. Непонятно тогда зачем городить огород, кроме как в исследовательских целях
                0
                Чтобы избежать сертификации достаточно не сертифицировать продукт, вот и все. Нет никаких ограничений ни на алгоритмы, ни на длину ключа для несертифицированных решений. А сертификация необходима только там, где законодательство прямо ее требует.

                Просто ГОСТовые алгоритмы шифрования, из-за отсутствия их аппаратной поддержки, оказываются гораздо медленней AES-а, из-за чего для практических целей они как правило менее предпочтительны. Поэтому очень мало для кого представляет интерес заниматься ими в случае, если нет заказчика, которому это действительно надо. А такой заказчик ровно один — государство — и для себя этот заказчик как правило требует еще и сертификацию решений. Если же не пытаться поставлять свои решения этому заказчику прямым или косвенным образом, то и требований по сертификации нет.

                Ограничение на длину ключа в 56 бит было в законодательстве США, для экспорта криптографических решений из Америки. К Российским алгоритмам, программам и разработкам это не имеет абсолютно никакого отношения.
                  0
                  ORLY?
                  3. Настоящим Положением необходимо руководствоваться при разработке, производстве, реализации и эксплуатации средств криптографической защиты информации конфиденциального характера в следующих случаях:
                  если информация конфиденциального характера подлежит защите в соответствии с законодательством Российской Федерации;

                  А это очень многое,
                  а Постановление Правительства РФ от 16.04.2012 N 313 относит действия автора к " ДЕЯТЕЛЬНОСТИ ПО РАЗРАБОТКЕ, ПРОИЗВОДСТВУ, РАСПРОСТРАНЕНИЮ ШИФРОВАЛЬНЫХ (КРИПТОГРАФИЧЕСКИХ) СРЕДСТВ,"
                  а, это уже лицензируемый вид деятельности.
                  Длинна ключа также прописана в Постановлении Правительства РФ от 16.04.2012 N 313…

                    0
                    Приведенная вами цитата из приказа ФСБ как раз и относится к тому заказчику, о котором я написал выше.

                    А у Постановления №313 такое количество исключений, что для того, чтобы под него подпадать, необходимо оказывать коммерческие услуги по разработке и использованию СКЗИ, чего автор явно не делает. И размер ключа в этом постановлении указан в том аспекте, что оно к малым ключам вовсе не относится, т.е. просто невозможно получить эту лицензию, предоставляя услуги по шифрованию с использованием коротких ключей.
                    0

                    ГОСТ 28147-89 при правильной реализации на AVX не уступает в скорости аппаратной реализации AES (AES-NI).

                      0
                      Вы хотите сказать, что производительность аппаратной реализации ГОСТ 28147-89 не хуже чем аппаратная реализация AES? С этим спорить не буду. Только вот аппаратная реализация AES есть чуть ли не у утюгов, а где есть аппаратная реализация ГОСТ 28147-89? В токенах, работающих по USB1/2?
                        0

                        Не, я имел в виду реализацию шифра ГОСТ 28147-89 на x86 с использованием расширения команд SSSE3/AVX.

            0
            У меня одного есть сомнения в полезности диска, который шифруется в 30 раз медленнее, судя по вашему тесту?
              0
              Глядя для чего вы используете шифрование. К тому же если вам нужна конфиденциальность, то потеря 2-10 секунд…
              0
              Не в Astra Linux ли все это ожидается?
                +1
                На Astra Linux не проверяли. На данный момент используем Debian 8 и Mageia.
                0
                Вообще-то хеш канонично называется streebog. А кузнечик хоть и не плох, но для него к сожалению нет аналога AES-NI. Но вообще такие модули могут быть весьма полезны.
                  0
                  Все по разному называют:

                  https://ru.wikipedia.org/wiki/ГОСТ_Р_34.11-2012

                  ↑ Матюхин Д. В., Шишкин В. А., Рудский В. И. Перспективный алгоритм хеширования // Доклад на конференции РусКрипто’2010,2010.
                  ↑ http://eprint.iacr.org/2013/556.pdf
                  ↑ «F. Mendel, N. Pramstaller, C. Rechberger, M. Kontak, J. Szmidt» CRYPTO 2008
                  ↑ Riham AlTawy, Aleksandar Kircanski and Amr M. Youssef. Rebound attacks on Stribog (2013).
                  ↑ Riham AlTawy and Amr M. Youssef. Integral Distinguishers for Reduced-round Stribog (2013).
                  ↑ http://www.streebog.info/ Открытый конкурс по исследованию функции
                  ↑ http://www.streebog.info/news/opredeleny-pobediteli-konkursa-po-issledovaniyu-khesh-funktsii-stribog/ Определены победители конкурса по исследованию хеш-функции «Стрибог»
                  ↑ Jian Guo, Jérémy Jean, Gaëtan Leurent, Thomas Peyrin, Lei Wang. The Usage of Counter Revisited: Second-Preimage Attack on New Russian Standardized Hash Function (2014).
                  ↑ Alex Biryukov, Léo Perrin, Aleksei Udovenko. The Secret Structure of the S-Box of Streebog, Kuznechik and Stribob (2015).
                  ↑ Alex Biryukov, Léo Perrin, Aleksei Udovenko. Reverse Engineering the S-Box of Streebog, Kuznechik and Stribob (2015).
                  ↑ [1]
                  ↑ GitHub — okazymyrov/stribog
                    0
                    Из приведенного списка во всех официальных названиях алгоритм транслитерируется именно как streebog. С ошибкой его иногда называют сторонние исследователи.
                    0
                    Ну, в libgcrypt-1.7.0 — это все stribog!!!
                      0
                      Отправьте багрепорт :)
                        0
                        Выпуск криптографической библиотеки Libgcrypt 1.7.0

                    0
                    Вы не пробовали тестировать производительности на процессорах с разной архитектурой?
                      0

                      Пока тесты проходили только на intel debian8 x64 и amd a10 mageia x64

                      0

                      А где ссылка на код проекта?

                        0
                        А не будет) Они взяли чужой код и добавили в свою библиотеку. Не выгодно выставлять готовое решение в open source)

                      Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                      Самое читаемое