
List of unsafe ed25519 signature libs
Список потенциально небезопасных библиотек подписи ed25519, которые предоставляют публичный API, позволяющий передавать секретный и открытый ключи независимо друг от друга в качестве входных данных функции подписи. Неправильное использование этих публичных API может привести к раскрытию закрытого ключа.
Большинство репозиториев из нашего анализа перечислены в IANIX :: Что использует Ed25519.
Количество затронутых библиотек: 45
Количество библиотек, исправивших проблему после объявления: 8
последнее обновление: 4 мая 2023 г.
Обратите внимание, что в обычном случае, согласно соответствующему rfc8032, подписи EdDSA детерминированы, и, таким образом, для одного и того же входного сообщения возвращается уникальный результат подписи, включающий два элемента: точку на кривой R и скаляр S.
Алгоритмическая деталь состоит в том, что открытый ключ подписывающего участвует в детерминированном вычислении только части S подписи, но не значения R. Последнее означает, что если бы злоумышленник каким-либо образом смог использовать функцию подписи как Oracle (принимающий произвольные открытые ключи на вход), то для одного и того же сообщения можно было бы получить две подписи с одинаковым R, различающиеся только частью S. К сожалению, когда это происходит, закрытый ключ можно легко извлечь; этот пост на StackOverflow объясняет, почему это возможно.
Тем не менее, публичные API НЕ должны допускать передачу раздельной пары закрытый/открытый ключ в качестве входных данных для подписи. Чтобы обойти это, многие реализации хранят открытый ключ вместе с закрытым ключом (или сидом) и считают всю пару ключей секретом ЛИБО всегда повторно вычисляют открытый ключ внутри функции подписи. К сожалению, большое количество существующих библиотек не решают эту проблему, допуская передачу произвольных открытых ключей на вход без проверки соответствия входного открытого ключа входному закрытому ключу.
Конечно, это не означает, что все приложения, зависящие от этих библиотек, подвержены атакам с раскрытием ключей; на самом деле большинство из них, вероятно, безопасны, поскольку обычно не предоставляют затронутый API своим пользователям и связывают пару открытый/закрытый ключ непосредственно перед вызовом sign. С другой стороны, даже когда эти API не открыты, существуют приложения с разными стратегиями модели угроз TCB в отношении того, как управляются и хранятся закрытые и открытые ключи. Тем не менее, чтобы предотвратить эту атаку, разработчикам следует также обеспечить протокол защиты целостности и для открытых ключей.
Здесь мы перечисляем некоторые затронутые библиотеки вместе с соответствующими ссылками на код.
Рис. 1. Пример неправильного использования API в Rust-крейте ed25519-dalek.
C: OpenGNB
https://github.com/gnbdev/opengnb/blob/master/libs/ed25519/sign.c#L7
C: GNU Nettle
https://github.com/gnutls/nettle/blob/fe7ae87d1b837e82f7c7968b068bca7d853a4cec/ed25519-sha512-sign.c#L43
ASM/C: iroha-ed25519 (Hyperledger Project)
https://github.com/hyperledger/iroha-ed25519/blob/main/lib/ed25519/ref10/ed25519.c#L27
и
https://github.com/hyperledger/iroha-ed25519/blob/main/lib/ed25519/amd64-64-24k-pic/ed25519.c#L30
C: ed25519-donna (Andrew Moon)
https://github.com/floodyberry/ed25519-donna/blob/master/ed25519.c#L59
C: ed25519 (Orson Peters)
https://github.com/orlp/ed25519/blob/master/src/sign.c#L7
C: libbrine (Kevin Smith)
https://github.com/kevsmith/libbrine/blob/master/src/ed25519/sign.c#L7
C++: Ed25519 (ArduinoLibs)
https://rweather.github.io/arduinolibs/classEd25519.html#a36ecf67b4c5d2d39a31888f56af1f8a5
C#: ed25519 (Hans Wolff)
https://github.com/hanswolff/ed25519/blob/master/Ed25519/Ed25519.cs#L146
C#: Ed25519 (CryptoManiac)
https://github.com/CryptoManiac/Ed25519/blob/972829ac688847895d5105f19ca1e5777131b421/Chaos.NaCl/Internal/Ed25519Ref10/keypair.cs#L7
Dart: ed25519_dart (Oleksii Semeshchuk)
https://github.com/semolex/ed25519_dart/blob/master/lib/src/ed25519_dart_base.dart#L200
C: Trezor firmware
Исправлено в этом PR: https://github.com/trezor/trezor-firmware/pull/2349 (Исправление внесено 27 июня 2022 г.)
Java: ed25519-elisabeth (Jack Grigg)
Исправлено в этом коммите: https://github.com/cryptography-cafe/ed25519-elisabeth/commit/49545ce47d550fed807522dff86546c812ccbbac (Исправление внесено 19 июня 2022 г.)
C: Harbour (Viktor Szakats)
Исправлено в этом коммите: https://github.com/vszakats/hb/commit/bae610b63d35c6c1793d94a3bf9467c3b1eded18 (Исправление внесено 30 июня 2022 г.)
Rust/Wasm: polkadot-js/wasm
Исправлено в этом PR: https://github.com/polkadot-js/wasm/pull/381/files (Исправление внесено 3 июля 2022 г.)
C: horse25519 (Yawning Angel)
Исправлено в этом PR: https://github.com/Yawning/horse25519/pull/3 (Исправление внесено 15 августа 2022 г.)
Erlang: erlang-libdecaf
Исправлено в этом коммите: https://github.com/potatosalad/erlang-libdecaf/commit/16ba07ea122660e95f6cfa9107e28ed58bada713. Логика рассмотрена в этом issue: ed25519-unsafe-libs/issues/7 (Исправление внесено 28 августа 2022 г.)
Rust: ed25519-dalek (Isis Agora Lovecruft)
Исправлено в этом PR: https://github.com/dalek-cryptography/ed25519-dalek/pull/205 (Исправление внесено 22 октября 2022 г.)
C: Monocypher (Loup Vaillant)
Исправлено в этом коммите: https://github.com/LoupVaillant/Monocypher/commit/da7b5407d20329f21a53ea993f516fb55e2f5e26 (Исправление внесено 27 февраля 2023 г.)
Библиотеки, изначально указанные как уязвимые, но исключённые из списка на основе отзывов сообщества.
Dart: riclava_ed25519 (riclava)
https://github.com/riclava/ed25519/blob/master/lib/ed25519.dart#L125
Clojure: ed25519 (Kevin Downey)
https://github.com/hiredman/ed25519/blob/master/src/ed25519/core.clj#L168
Haskell: hs-scraps (Vincent Hanquez)
https://github.com/vincenthz/hs-scraps/blob/master/Crypto/Signature/Ed25519.hs#L115
Java: ed25519-java (k3d3)
https://github.com/k3d3/ed25519-java/blob/master/ed25519.java#L144
Java: ed25519 (Bjorn Arnelid)
https://github.com/BjornArnelid/ed25519/blob/master/src/ed25519/application/Ed25519.java#L32
Java: Punisher.NaCl (Arpan Jati)
https://github.com/arpanj/Punisher.NaCl/blob/c9619ca3028b90d0556c0473e4eba1d429a3744c/Punisher.NaCl/src/Punisher/NaCl/Ed25519Operations.java#L72
Java: ED25519 (Mick Michalski)
https://github.com/michami/ED25519/blob/master/ED25519.java#L60
Java: vRallev/ECC-25519 (Ralf Wondratschek)
https://github.com/vRallev/ECC-25519/blob/master/ECC-25519-Java/src/main/java/net/vrallev/java/ecc/Ecc25519Helper.java#L102
Perl: Crypt::Ed25519 (Marc Lehmann)
https://metacpan.org/release/MLEHMANN/Crypt-Ed25519-0.9/view/Ed25519.pm#$signature-=-Crypt::Ed25519::sign-$message,-$public_key,-$private_key
Python: ed25519.py (Ed25519 authors)
https://ed25519.cr.yp.to/python/ed25519.py
Python: ed25519 (Python Cryptographic Authority)
https://github.com/pyca/ed25519/blob/main/ed25519.py#L243
(авторы упоминают, что она в любом случае небезопасна относительно побочных каналов)
Python: python-pure25519 (Brian Warner)
https://github.com/warner/python-pure25519/blob/master/pure25519/eddsa.py#L21
Python: nmed25519 (naturalmessage)
https://github.com/naturalmessage/nmed25519/blob/master/nmed25519.py#L150
Python: ed25519.py (Shiho Midorikawa)
https://gist.github.com/elliptic-shiho/f41fd75cc30646a61d7ad63043fdd56e#file-ed25519-py-L77
Python: привязки для ed25519-dalek: py-ed25519-bindings
https://github.com/polkascan/py-ed25519-bindings/blob/master/src/lib.rs#L111
Swift: ed25519swift (pebble8888)
https://github.com/pebble8888/ed25519swift/blob/master/Ed25519ref/ed25519s.swift#L120
JS: supercop.js (1p6 Flynx)
https://github.com/1p6/supercop.js/blob/master/index.js#L29
JS: substack/ed25519-supercop (James Halliday)
https://github.com/substack/ed25519-supercop/blob/master/index.js#L3
C: libeddsa (Philipp Lay)
https://github.com/phlay/libeddsa/blob/master/lib/ed25519-sha512.c#L85
C#: SommerEngineering/Ed25519 (Thorsten Sommer)
https://github.com/SommerEngineering/Ed25519/blob/master/Ed25519/Signer.cs#L80
CUDA: ChorusOne/solanity
https://github.com/ChorusOne/solanity/blob/master/src/cuda-ecc-ed25519/sign.cu#L10
C: ncme/c25519 (Daniel Beer и Nikolas Rösener)
https://github.com/ncme/c25519/blob/master/src/edsign.c#L115
C: luazen (Phil Leblanc)
https://github.com/philanc/luazen/blob/master/src/x25519.c#L508 (авторы изменили функцию, чтобы она принимала pk вместо исходного 64-байтового sk из NaCl, который включает pk в качестве последних 32 байтов)
C++: amber (Pelayo Bernedo)
https://github.com/bernedogit/amber/blob/master/src/group25519.cpp#L1661
C: FLD ECC AVX2 (Armando Faz-Hern'{a}ndez и Julio L'{o}pez и Ricardo Dahab)
https://github.com/armfazh/fld-ecc-vec/blob/master/src/sign255.c#L391
Elixir: mwmiller/ed25519_ex (Matt Miller)
https://github.com/mwmiller/ed25519_ex/blob/master/lib/ed25519.ex#L146(Открытый ключ необязателен. По комментарию автора: если предоставлен только секретный ключ, открытый ключ будет вычислен из него. Это добавляет значительные накладные расходы)
PHP (C-обёртка): php-ed25519-ext
https://github.com/encedo/php-ed25519-ext/blob/master/ed25519-ext.c#L93
Nim: niv/ed25519.nim (Bernhard Stöckner)
https://github.com/niv/ed25519.nim/blob/master/ed25519.nim#L26
Typescript: mipher (Marco Paland)
https://github.com/mpaland/mipher/blob/master/src/x25519.ts#L936
Lua: LuaMonocypher
https://github.com/philanc/luamonocypher/blob/main/src/luamonocypher.c#L268
Crystal: monocypher.cr
https://github.com/konovod/monocypher.cr/blob/master/src/monocypher.cr#L39
Python: py_ssh_keygen_ed25519 (Péter Szabó)
https://github.com/pts/py_ssh_keygen_ed25519/blob/master/ed25519_compact.py#L128 (Открытый ключ необязателен)
Javascript: KinomaJS
https://github.com/Kinoma/kinomajs/blob/701879d37e7fe5001420e0053cd60df6b91e4553/xs6/extensions/crypt/crypt_ed25519.js#L92 (Открытый ключ необязателен)
Haskell: gen-ed25-keypair
https://github.com/awakesecurity/gen-ed25-keypair
C: horse25519 (Yawning Angel)
https://github.com/Yawning/horse25519/blob/master/src/ref10/sign.c#L7 Примечание: этот репозиторий включает копию реализации ed25519 ref10 от djb, взятую из supercop, чтобы не привлекать ещё одну зависимость, однако цель — предоставить автономный исполняемый файл для генерации vanity-пар ключей ed25519. Хотя API используется необычным образом, это намеренно, поскольку проект и так делает нечто крайне экзотическое и нестандартное в отношении генерации ключей, и библиотека не предназначена для подписи.