
Автоматизированный инструмент дифференциального фаззинга для криптографического программного обеспечения, который обнаруживает ошибки реализации, сбои соответствия и утечки по побочным каналам с помощью интеллектуального параллельного тестирования на нескольких языках и платформах.
CDF — это инструмент для автоматической проверки корректности и безопасности криптографического программного обеспечения. CDF может обнаруживать ошибки реализации, несоответствия стандартам, утечки по побочным каналам и т.д.
CDF реализует комбинацию модульных тестов с «дифференциальным фаззингом» — подходом, который сравнивает поведение различных реализаций одних и тех же примитивов при подаче граничных случаев и значений, максимизирующих покрытие кода.
В отличие от универсальных фаззеров и тестового ПО, CDF:
Умный: CDF знает, какой алгоритм тестируется, и адаптируется к тестируемым функциям
Быстрый: CDF тестирует только то, что нужно, и максимально параллелизует тесты
Многофункциональный: CDF не привязан к какому-либо языку или API, поддерживает произвольные исполняемые программы или скрипты
Портативный: CDF будет работать на любой платформе Unix или Windows, так как написан на Go без каких-либо платформо-зависимых зависимостей
Цель CDF — предоставить разработчикам и исследователям безопасности более эффективный инструмент тестирования, который эффективнее тестовых векторов и дешевле ручного аудита формальной верификации.
CDF был впервые представлен на Black Hat USA 2017. Вы можете ознакомиться со слайдами нашей презентации, которые содержат общую информацию об обосновании и дизайне CDF.
CDF написан на Go, текущая версия разработана с использованием Go 1.8. У него нет зависимостей, кроме стандартной библиотеки Go.
Однако мы предоставляем примеры программ для тестирования с помощью CDF, которые написаны на C, Python, C++, Java и Go и требуют для запуска специальных криптографических библиотек. В настоящее время требуются следующие библиотеки:
make соберет бинарный файл cdf.
Несколько примеров программ доступны в example: make examples-all соберет все примеры, а make examples-go — только примеры на Go.
make test запустит модульные тесты (CDF).
Для начала вы можете просмотреть информацию об использовании, запустив cdf -h.
Затем вы можете попробовать пример, такой как интерфейс rsaenc, с примерами на Go и CryptoPP для RSA OAEP. Считая CryptoPP эталоном, вы можете протестировать реализацию Go, выполнив:
cdf rsaenc /examples/oaep_rsa2048_go /examples/oaep_rsa2048_cryptopp
Эта команда выполнит различные тесты, специфичные для интерфейса rsaenc.
В этом примере CDF должен пожаловаться на максимальный размер открытого экспонента, поддерживаемый реализацией Go: если мы проверим его код, то увидим, что открытый экспонент хранится как обычное целое число, тогда как в CryptoPP (и большинстве других реализаций) он хранится как большое целое. Это, однако, сделано намеренно и, вероятно, не будет изменено.
Параметры определены в config.json.
Большинство параметров понятны. Вы можете захотеть установить другие приватные ключи для rsaenc и ecdsa (эти интерфейсы тестируются с фиксированными ключами, хотя некоторые параметры ключей, такие как экспоненты, изменяются в некоторых тестах).
Параметр seed позволяет изменить зерно, используемое в псевдослучайных генераторах CDF. (Однако тестируемая программа может использовать какой-либо другой инициализированный PRNG, как, например, примеры OAEP.) Параметр concurrency позволяет задать количество конкурентных горутин, которые CDF должен порождать при запуске программ. Имейте в виду, что лучше держать это число ниже реального количества ядер. Параметр verboseLog, если установлен в true, будет записывать все входные и выходные данные программ, даже для успешных тестов, в файл log.txt.
Чтобы протестировать ваше ПО с помощью CDF, вы должны создать программу, которая читает ввод и выводит результат в соответствии с интерфейсами CDF, и внутри вызывает тестируемую программу. Интерфейсы CDF — это абстракции криптографической функциональности, позволяющие проводить тестирование черного ящика произвольных реализаций.
Например, если вы реализовали схему подписи ECDSA, ваша программа должна удовлетворять интерфейсу ecdsa и, таким образом, принимать в качестве входных данных 4 или 5 аргументов,
соответственно для подписи сообщения или верификации подписи. Эти аргументы: открытая координата X, открытая координата Y, приватное большое целое D и сообщение, которое вы хотите подписать, и затем она должна выводить только большие целые R и S, каждое на новой строке. Или, для верификации сообщения, она должна принимать X, Y, R, S и сообщение и затем выводить только True или False. Спецификации интерфейсов подробно описаны ниже.
Наши примеры реализаций интерфейсов помогут вам создать свои собственные.
Обработка ошибок оставлена на усмотрение тестируемой программы, однако для получения осмысленных ошибок в CDF лучше завершать работу при сбое, возвращать код ошибки и выводить сообщение об ошибке.
Программа интерфейса может быть написана на любом языке, ей просто нужно быть исполняемым файлом, соответствующим интерфейсу CDF. Программа интерфейса обычно написана на том же языке, что и тестируемая программа, но это не обязательно (это может быть обёртка на другом языке, например, для Java-программ).
CDF в настоящее время поддерживает следующие интерфейсы, где параметры кодируются как шестнадцатеричные строки ASCII, если не указано иное:
Интерфейс dsa тестирует реализации алгоритма цифровой подписи (DSA). Он должен поддерживать операции подписи и верификации:
| Операция | Вход | Выход |
|---|---|---|
| Подпись | p q g y x m | r s |
| Верификация | p q g y r s m | истинностное значение |
Здесь p, q, g — параметры DSA, y — открытый ключ, x — закрытый ключ, m — сообщение, r и s образуют подпись, которая должна возвращаться разделённой новой строкой. Истинностное значение, либо «true», либо «false», представлено в виде строки.
Интерфейс dsa поддерживает опциональный тест: флаг -h позволяет обойти процесс хеширования и напрямую
предоставить хеш-значение для подписи. Это позволяет CDF выполнять больше тестов, например, проверку переполнений или усечения хеша.
Интерфейс ecdsa тестирует реализации алгоритма цифровой подписи на эллиптических кривых (ECDSA). Он должен поддерживать операции подписи и верификации:
| Операция | Вход | Выход |
|---|---|---|
| Подпись | x y d m | r s |
| Верификация | x y r s m | истинностное значение |
Здесь x и y — координаты открытого ключа ECDSA, d — закрытый ключ, m — сообщение, а r и s образуют подпись, которая должна возвращаться разделённой новой строкой. Истинностное значение, либо «true», либо «false», представлено строкой.
Флаг -h служит той же цели, что и в dsa.
Пожалуйста, обратите внимание, что наша текущая конструкция предполагает фиксированную кривую, определённую в тестируемой программе.
Для получения воспроизводимых результатов с этими тестами и использования всех возможностей обнаружения CDF вам нужно либо инициализировать генератор случайных чисел фиксированным зерном, либо использовать детерминированный вариант ECDSA, иначе CDF не сможет автоматически обнаруживать такие проблемы, как повторяющиеся метки (same tags issues).
Интерфейс enc тестирует операции симметричного шифрования и дешифрования, обычно выполняемые с блочным шифром (поточные шифры можно тестировать с помощью интерфейса prf). Он должен поддерживать шифрование и дешифрование:
| Операция | Вход | Выход |
|---|---|---|
| Шифрование | k m | c |
| Дешифрование | k c | r |
Здесь k — ключ, m — сообщение, c — шифротекст, r — восстановленный открытый текст.
Интерфейс prf тестирует ключевое хеширование (псевдослучайные функции, MAC), а также поточные шифры:
| Операция | Вход | Выход |
|---|---|---|
| Вычисление | k m | h |
Здесь k — ключ, m — сообщение (или nonce в случае поточного шифра), а h — результат вычисления PRF. Наш интерфейс предполагает фиксированный размер ключа и переменную длину ввода. Если необходимо указать конкретный ключ, то тестируемая программа должна игнорировать ввод ключа, или, возможно, лучше использовать интерфейс xof.
| Операция | Вход | Выход |
|---|---|---|
| Шифрование | n e m | c |
| Дешифрование | p q e d c | r |
Здесь n — модуль, e — открытый экспонент (для совместимости с некоторыми библиотеками e также требуется для дешифрования), m — сообщение, p и q — множители n (такие, что p > q, поскольку библиотеки обычно требуют этого), d — закрытый экспонент, а r — восстановленный открытый текст.
Интерфейс xof тестирует хеш-функции, функции с расширяемым выводом (XOF), детерминированные генераторы случайных битов (DRBG):
| Операция | Вход | Выход |
|---|---|---|
| Вычисление | m | h |
Здесь m — сообщение, h — результат.
CDF основан на первоначальных идеях JP Aumasson, впервые представленных на WarCon 2016, и большая часть кода была написана Yolan Romailler.
CDF является объектом авторского права (c) 2016-2017 Nagravision SA, все права защищены.
CDF выпущен под лицензией GPLv3.