
List of unsafe ed25519 signature libs
Un elenco di librerie di firma ed25519 potenzialmente non sicure che espongono un'API pubblica in cui chiave segreta e chiave pubblica possono essere fornite indipendentemente come input della funzione di firma. Un uso improprio di queste API pubbliche può portare all'esposizione della chiave privata.
La maggior parte dei repository nella nostra analisi è elencata in IANIX :: Cose che usano Ed25519.
Numero di librerie interessate: 45
Numero di librerie che hanno corretto il problema dopo l'annuncio: 8
ultimo aggiornamento: 4 maggio 2023
Nota: normalmente e secondo il relativo rfc8032, le firme EdDSA sono deterministiche e quindi, per lo stesso messaggio di input da firmare, viene restituito un output di firma unico che include due elementi: un punto della curva R e uno scalare S.
Un dettaglio algoritmico è che la chiave pubblica del firmatario è coinvolta solo nel calcolo deterministico della parte S della firma, ma non nel valore R. Ciò implica che se un avversario potesse in qualche modo usare la funzione di firma come un Oracle (che accetta chiavi pubbliche arbitrarie come input), sarebbe possibile ottenere, per lo stesso messaggio, due firme che condividono lo stesso R e differiscono solo nella parte S. Purtroppo, quando ciò accade, si può facilmente estrarre la chiave privata; questo post su StackOverflow spiega perché ciò è fattibile.
Detto questo, le API pubbliche NON dovrebbero consentire una coppia di chiavi privata/pubblica disaccoppiata come input di firma. Per ovviare a questo problema, molte implementazioni memorizzano la chiave pubblica insieme alla chiave privata (o seed) e considerano l'intera coppia di chiavi come segreta, oppure derivano nuovamente la chiave pubblica all'interno della funzione di firma. Purtroppo, un gran numero di librerie esistenti non affronta il problema, consentendo chiavi pubbliche arbitrarie come input senza verificare che la chiave pubblica corrisponda alla chiave privata inserita.
Ovviamente, ciò non significa che tutte le applicazioni con dipendenze da queste librerie siano esposte ad attacchi di esposizione delle chiavi; in realtà, la maggior parte è probabilmente al sicuro perché di solito non espone pubblicamente l'API interessata ai propri utenti e accoppia la coppia di chiavi pubbliche/private subito prima dell'invocazione di sign. D'altro canto, anche quando queste API non sono esposte, esistono applicazioni con diverse strategie di threat model TCB su come le chiavi private e pubbliche vengono gestite e memorizzate. Detto questo, per prevenire questo attacco, gli sviluppatori dovrebbero inoltre implementare un protocollo di protezione dell'integrità anche per le chiavi pubbliche.
Qui elenchiamo alcune librerie interessate insieme ai relativi riferimenti al codice.
Fig. 1. Un esempio di uso improprio dell'API nella crate 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
e
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
Corretto in questa PR: https://github.com/trezor/trezor-firmware/pull/2349 (Fix integrato il 27 giugno 2022)
Java: ed25519-elisabeth (Jack Grigg)
Corretto in questo commit: https://github.com/cryptography-cafe/ed25519-elisabeth/commit/49545ce47d550fed807522dff86546c812ccbbac (Fix integrato il 19 giugno 2022)
C: Harbour (Viktor Szakats)
Corretto in questo commit: https://github.com/vszakats/hb/commit/bae610b63d35c6c1793d94a3bf9467c3b1eded18 (Fix integrato il 30 giugno 2022)
Rust/Wasm: polkadot-js/wasm
Corretto in questa PR: https://github.com/polkadot-js/wasm/pull/381/files (Fix integrato il 3 luglio 2022)
C: horse25519 (Yawning Angel)
Corretto in questa PR: https://github.com/Yawning/horse25519/pull/3 (Fix integrato il 15 agosto 2022)
Erlang: erlang-libdecaf
Corretto in questo commit: https://github.com/potatosalad/erlang-libdecaf/commit/16ba07ea122660e95f6cfa9107e28ed58bada713. Logica affrontata in questo issue: ed25519-unsafe-libs/issues/7 (Fix integrato il 28 agosto 2022)
Rust: ed25519-dalek (Isis Agora Lovecruft)
Corretto in questa PR: https://github.com/dalek-cryptography/ed25519-dalek/pull/205 (Fix integrato il 22 ottobre 2022)
C: Monocypher (Loup Vaillant)
Corretto in questo commit: https://github.com/LoupVaillant/Monocypher/commit/da7b5407d20329f21a53ea993f516fb55e2f5e26 (Fix integrato il 27 febbraio 2023)
Librerie originariamente segnalate come vulnerabili, ma rimosse dall'elenco in base al feedback della community.
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
(gli autori ricordano che è comunque non sicuro contro i canali laterali)
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: binding per 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 e 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 (gli autori hanno modificato la funzione per accettare pk al posto dell'sk originale di 64 byte di nacl, che include pk come ultimi 32 byte)
C++: amber (Pelayo Bernedo)
https://github.com/bernedogit/amber/blob/master/src/group25519.cpp#L1661
C: FLD ECC AVX2 (Armando Faz-Hern'{a}ndez e Julio L'{o}pez e 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(La chiave pubblica è opzionale. Secondo il commento dell'autore: se viene fornita solo la chiave segreta, la chiave pubblica verrà derivata da essa. Questo aggiunge un overhead significativo)
PHP (C wrapper): 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 (La chiave pubblica è opzionale)
Javascript: KinomaJS
https://github.com/Kinoma/kinomajs/blob/701879d37e7fe5001420e0053cd60df6b91e4553/xs6/extensions/crypt/crypt_ed25519.js#L92 (La chiave pubblica è opzionale)
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 Nota: questo repository include una copia dell'implementazione ref10 ed25519 di djb presa da supercop per evitare di aggiungere un'altra dipendenza, ma l'intento è fornire un eseguibile autonomo che genera coppie di chiavi vanity ed25519. Sebbene utilizzi l'API in modo insolito, è intenzionale, poiché sta già facendo qualcosa di estremamente esotico e insolito rispetto alla generazione delle chiavi, e la libreria non è pensata per la firma.