Skip to content

Latest commit

 

History

20 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

bcrypto-test-stand

Тестовый стенд для лабораторий, испытывающих СКЗИ в Беларуси.

При испытаниях СКЗИ по методикам, опубликованным ОАЦ, для ряда алгоритмов требуется проводить тесты, подразумевающие сравнение с эталонной реализацией.

Перед началом работы с данным продуктом следует:

  • зарегистрировать (создать JSON-конфиг в /samples/) тестируемые/эталонные обрацы
  • зарегистрировать дополнительные режимы тестирования (при необходимости)

Стенд позволяет провести N тестов в произвольном количестве режимов для 2+ образцов. Режимы тестируются последовательно. Для каждого режима по его JSON-конфигу (/modes/) определяется перечень и длины входных параметров (либо специфический генератор из /generators/, который следует использовать в данном режиме). Стенд вырабатывает необходимые параметры и вызывает тестовые образцы, проверяя что выводы непустой и совпадают для всех тестовых образцов.

Результаты тестирования сохраняются в /reports/ и выводятся в консоль.

При расхождении печатаются входные данные и вывод каждой программы — чтобы разницу можно было изучить вручную.

Важно отметить, что в ряде случаев в эталонах, предоставленных по умолчанию, используются hard-coded параметры. Например, для открытых ключей ЭЦП и разделения секрета. Во всех таких случаях используемые параметры взяты из соответствующих методик. Дополнительный пример hard-coded параметра - длина генерируемой последовательности в brng-hmac-hbelt -- она составляет 64 блока, поскольку так указано в тесте. Если вам удобно иметь и это значение (n) в качестве параметра при вызове собственного образца -- реализуйте для него значение 64 по умолчанию.

Структура проекта

run.py          точка входа
samples/        JSON файлы, регистрирующие тестовые образцы. В default/ содержатся эталонные образцы на основе bee2
modes/          JSON файлы, регистрирующие режимы тестирования (алгоритмы)
generators/     генераторы для нерегулярных режимов (merge, brng-hmac-hbelt)
static/         JSON файлы тестов известного ответа (по категориям)
boomerang/      JSON файлы бумеранг-тестов (по категориям)
src/            реализация стенда
bin/            исполняемые файлы (помещайте сюда образцы для тестирования)

Проверка доступных образцов и режимов

Вывод доступных образцов для тестирования: python3 run.py list-samples

Вывод поддерживаемых режимов тестирования: python3 run.py list-modes

Вывод тестов известного ответа по категориям: python3 run.py list-static

Вывод бумеранг-тестов по категориям: python3 run.py list-boomerang

Запуск

python run.py <образец> <образец> [<образец> ...] [--modes <режим> ...] [-n <n>] [--verbose]

Укажите два или более образца, у которых есть хотя бы один общий режим:

python run.py bee2recent mybuild
python run.py bee2recent mybuild --modes belt-kwp belt-dwp
python run.py bee2recent mybuild --modes all -n 1000 --verbose
  • --modes — какие режимы прогнать, либо all для всех режимов, поддерживаемых каждым из выбранных образцов. По умолчанию all.
  • -n — число итераций на режим (по умолчанию 500).
  • --verbose — печатать входные данные и вывод для каждого теста, а не только для упавших.

Тесты известного ответа

Помимо сравнения образцов, стенд умеет проверять один образец на соответствие известному ответу из методики.

python run.py static <образец> [<категория>|all] [--verbose]

Категория — это семейство алгоритмов (belt, bels, bign, brng); по умолчанию all. Векторы хранятся в static/<категория>/<режим>.json, по одному файлу на режим:

{
  "mode": "belt-ctr",
  "doc": "STB 34.101.31-2020",
  "tests": [
    {"id": "BELT.CTR.1", "params": ["<hex>", "<hex>", "<hex>"], "output": "<ожидаемый stdout>"}
  ]
}
  • params — в порядке параметров режима (как и при сравнении), поэтому alias образца применяется автоматически.
  • output — ожидаемый stdout, то есть известный ответ из методики.
  • expectequal (по умолчанию) либо not_equal для негативных тестов.

Параметр вида {"file": "<путь>"} передаётся образцу как абсолютный путь к файлу (относительно каталога теста) — для входных данных, которые слишком велики для аргумента командной строки.

Образец вызывается так же, как при сравнении; его stdout сверяется с output. Режимы, которые образец не поддерживает, пропускаются.

Бумеранг-тесты

Бумеранг-тест многократно вырабатывает случайные входные данные, выполняет цепочку вызовов образца (прямую операцию и обратную к ней) и проверяет, что результат совпадает с исходным значением.

python run.py boomerang <образец> [<категория>|all] [-n <раундов>] [--verbose]

Описания хранятся в boomerang/<категория>/<тест>.json, по одному файлу на тест:

{
  "id": "BELT.CTR.4",
  "doc": "STB 34.101.31-2020",
  "rounds": 1000,
  "inputs": [
    {"name": "x",   "bytes": 2048},
    {"name": "key", "bytes": 32},
    {"name": "s",   "bytes": 16}
  ],
  "steps": [
    {"mode": "belt-ctr", "params": ["x", "key", "s"], "out": "y"},
    {"mode": "belt-ctr", "params": ["y", "key", "s"], "out": "x2"}
  ],
  "assert_equal": ["x2", "x"]
}
  • inputs — случайные входные слоты (имя и длина в байтах), вырабатываются заново каждый раунд.
  • steps — последовательность вызовов; out сохраняет stdout шага под указанным именем.
  • assert_equal — два значения, которые должны совпасть в каждом раунде.

Токен в params и assert_equal означает: @литерал — литеральное значение; имя.head:N / имя.tail:N — значение без последних N байт либо последние N байт; иначе имя — входной слот или вывод предыдущего шага.

rounds задаёт число раундов по умолчанию; -n переопределяет его.

Добавление образца

Положите JSON-файл в samples/; имя файла без .json — это имя, которое вы будете передавать в командной строке в качетве названия продукта.

{
  "path": "bin/mybuild.exe",
  "cmd": "wine",
  "modes": [
    {"name": "belt-cfb", "alias": "cfb"},
    {"name": "belt-ctr", "alias": "ctr"},
    {"name": "belt-mac"}
  ],
  "tag": "mybuild"
}
Ключ Обязательность Значение
path да Путь к исполняемому файлу — относительно корня проекта или абсолютный
modes да Режимы, которые поддерживает программа (см. ниже)
cmd нет Интерпретатор или обёртка для запуска, например wine, luajit
tag нет Метка в выводе. По умолчанию — имя исполняемого файла

Каждая запись в modes называет режим, поддерживаемый программой. Программа может ожидать в командной строке имя режима в формате, отличном от зарегистрированных здесь (например, cfb вместо belt-cfb). Чтобы дать стенду понять, что в вашей программе под cfb понимается belt-cfb, укажите alias для данного режима при регистрации образца: {"name": "belt-cfb", "alias": "cfb"}.

Каждый образец вызывается как [cmd] <path> <режим-или-alias> <параметр1> <параметр2> ..., и сравнивается его stdout.

Интерпретаторы по платформам

cmd действует на всех платформах. Чтобы переопределить его для конкретной платформы, добавьте соответствующий ключ — побеждает самый специфичный:

Ключ Платформа
cmd_win Windows
cmd_linux Linux x86-64
cmd_linux_arm Linux ARM64
cmd_mac macOS Intel
cmd_mac_arm macOS Apple Silicon

Удобно, когда, например, Windows-.exe запускается на Windows нативно, а на остальных платформах — через wine.

Добавление режима

Режим — это рецепт генерации входных данных одного теста. Положите JSON-файл в modes/; имя файла без .json — каноническое имя режима. Режим бывает декларативным либо скриптовым — ровно одно из двух.

Необязательная строка docs (например, ссылка на стандарт) показывается командой list-modes.

Декларативный режим — случайные hex-параметры фиксированного размера

{
  "docs": "STB 34.101.31-2020 (7.3)",
  "params": [
    {"name": "x",   "bytes": 2048},
    {"name": "key", "bytes": 32},
    {"name": "s",   "bytes": 16}
  ]
}

Каждый параметр становится одним аргументом командной строки из bytes случайных байт в виде шестнадцатеричной строки в верхнем регистре. name используется только для подписи в выводе.

Скриптовый — специфическая логика при генерации параметров теста

Когда фиксированных размеров недостаточно, укажите режиму генератор в generators/:

{
  "docs": "STB 34.101.60-2014 (7.4)",
  "generator": "merge",
  "options": {
    "size":     32,
    "slots":    5,
    "fill_min": 2,
    "fill_max": 5
  }
}

generator называет generators/<имя>.py. Всё из options передаётся ему. Необязательный массив param_names подписывает сгенерированные аргументы в выводе; без него они показываются как Param1, Param2 и т. д.

Так, например, длина параметров key и synchro для brng-hmac-hbelt зависит от номера текущего теста: (i mod 64) + 1 для key, (i mod 32) + 1 для synchro, где i - номер теста.

Тест merge подразумевает, что часть из пяти аргументов будут пустыми (""). Передача пустых аргументов в данном случае позволяет определить индексы используемых открытых ключей (см. описание теста в методике испытаний).

Написание генератора для скриптового режима

Генератор — это модуль на Python в generators/, определяющий единственную функцию generate, которая возвращает упорядоченный список строк-аргументов:

from src.util import rng_hex

def generate(rng, options, index):
    # rng     : random.Random — вся случайность проходит через этот экземпляр
    # options : dict[str, str] — объект "options" режима
    # index   : 1-based номер теста, полезен для размеров, зависящих от индекса
    size = int(options.get("size", 32))
    return [rng_hex(rng, size), rng_hex(rng, size)]

rng_hex(rng, n_bytes) возвращает n_bytes случайных байт в виде hex в верхнем регистре. Пустая строка в слоте передаёт пустой аргумент — так merge оставляет часть долей незаполненными.

Имя генератора следует указывать в поле "generator" при регистрации режима.

Поддерживаемые режимы

В bin/default/ поставляются две эталонные сборки bee2: bee2recent.exe (актуальная) и bee2old.exe. Вместе они покрывают разные, непересекающиеся режимы, поэтому сравнивать их друг с другом нельзя — зарегистрируйте свой образец и сравните его с той сборкой, что покрывает нужные режимы.

Режим Документ Реализация в bin/default/
belt-cfb STB 34.101.31-2020 (7.3) bee2old
belt-ctr STB 34.101.31-2020 (7.4) bee2old
belt-mac STB 34.101.31-2020 (7.5) bee2old
belt-hash STB 34.101.31-2020 (7.8) bee2old
belt-dwp STB 34.101.31-2020 (7.6, схема 1) bee2recent
belt-kwp STB 34.101.31-2020 (7.7) bee2recent
bign-with-hbelt STB 34.101.45-2013 (7.1) bee2recent
bign-keytransport STB 34.101.45-2013 (7.2) bee2recent
bels-share-split STB 34.101.60-2014 (7.3) bee2recent
bels-share-merge STB 34.101.60-2014 (7.4) bee2recent
brng-ctr-hbelt STB 34.101.47-2017 (6.2)
brng-hmac-hbelt STB 34.101.47-2017 (6.3) bee2recent
hotp-hbelt STB 34.101.47-2013 (A.7) bee2recent

Прочерк означает, что режим определён, но ни одна из эталонных сборок его пока не реализует.

Эталонные реализации

C исходными текстами bee2recent.exe можно ознакомиться здесь. Исходные тексты для bee2old.exe утрачены.

В качестве эталонных реализаций используется bee2 доработанная исключительно в рамках адаптации к тестам методик и в части вывода необходимых cli-интерфейсов для поддерживаемых режимов.

Следует отметить, что эталоном в смысле методик испытаний называется СКЗИ, прошедшее процедуру сертификации, и на момент написания данного текста bee2 не является сертифицированным продуктом.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages