- Ditemukan kesalahan validasi titik yang tidak tepat pada kurva Edwards25519 di fungsi tingkat rendah
crypto_core_ed25519_is_valid_point() milik libsodium
- Fungsi ini seharusnya memeriksa apakah sebuah titik termasuk dalam grup kriptografi utama, tetapi secara keliru meloloskan sebagian titik dari ordo campuran (subgroup)
- Penyebabnya adalah bug kode pada validasi koordinat internal yang hanya memeriksa X=0 dan melewatkan verifikasi Y=Z, sehingga titik yang salah bisa diperlakukan sebagai valid
- Pada versi perbaikan, logika diubah agar memeriksa kedua kondisi (X=0, Y=Z), dan versi 1.0.20 ke bawah atau rilis sebelum 30 Desember 2025 terdampak
- API tingkat tinggi (
crypto_sign_*) tidak terdampak, dan penggunaan grup Ristretto255 direkomendasikan dari sisi keamanan maupun performa
Gambaran umum proyek libsodium
- libsodium adalah proyek yang dimulai 13 tahun lalu dengan tujuan menyediakan API sederhana agar kriptografi mudah digunakan
- Dirancang agar pengguna dapat melakukan operasi tingkat tinggi tanpa perlu memahami algoritme internal
- Proyek ini menekankan kompatibilitas API, dan menjaga konsistensi hingga sekarang berdasarkan API NaCl
- Karena sebagian pengguna memakai fungsi tingkat rendah secara langsung melampaui batasan yang dijelaskan dalam dokumentasi, semakin banyak kasus di mana library ini digunakan layaknya toolkit kriptografi
Penyebab bug yang ditemukan
- Fungsi yang bermasalah:
crypto_core_ed25519_is_valid_point()
- Pada kurva Edwards25519, fungsi ini seharusnya menolak titik yang tidak termasuk dalam grup utama (berordo L)
- Namun, sebagian titik dengan ordo campuran (2L, 4L, 8L, dll.) lolos validasi
- Secara internal, fungsi mengalikan titik dengan L untuk memeriksa ordonya, lalu memeriksa apakah hasilnya adalah titik identitas (identity)
- Titik identitas direpresentasikan dalam bentuk X=0, Y=Z, tetapi kode lama hanya memeriksa X=0
- Akibatnya, titik salah dengan Y≠Z dapat diperlakukan sebagai valid
- Contoh: untuk titik Q di grup utama, menambahkan titik berordo 2
(0, -1) menjadi Q+(0, -1) menghasilkan titik yang salah, tetapi sebelum perbaikan titik ini tetap lolos
Isi perbaikan
- Commit patch diubah sebagai berikut
- Kode lama:
return fe25519_iszero(pl.X);
- Kode baru:
fe25519_sub(t, pl.Y, pl.Z); return fe25519_iszero(pl.X) & fe25519_iszero(t);
- Kini kedua syarat X=0 dan Y=Z diperiksa agar validasi berjalan benar
Cakupan dampak
- Berpotensi terdampak jika memenuhi kondisi berikut
- Menggunakan versi 1.0.20 ke bawah atau rilis sebelum 30 Desember 2025
- Memvalidasi titik input yang tidak tepercaya dengan
crypto_core_ed25519_is_valid_point()
- Mengimplementasikan operasi kurva Edwards25519 secara langsung
- Namun, sebagian besar pengguna tidak terdampak
- API tingkat tinggi (
crypto_sign_*) tidak menggunakan fungsi tersebut
crypto_scalarmult_ed25519 tidak menyebabkan kebocoran informasi meskipun diberi kunci publik yang salah
- Kunci yang dibuat oleh
crypto_sign_keypair dan crypto_sign_seed_keypair berada dalam grup yang benar
Tindakan yang disarankan
- Disarankan menggunakan grup Ristretto255
- Sudah disertakan di libsodium sejak 2019 dan menyelesaikan masalah terkait cofactor
- Titik hasil decoding otomatis aman, sehingga tidak memerlukan validasi tambahan
- Menawarkan performa operasi yang lebih cepat daripada Edwards25519
- Jika tidak memungkinkan untuk melakukan pembaruan, validasi dapat dilakukan dengan fungsi alternatif tingkat aplikasi yang disarankan (
is_on_main_subgroup)
Distribusi perbaikan dan dukungan
- Masalah ini diperbaiki segera setelah ditemukan, dan sudah disertakan dalam semua versi stabil yang didistribusikan setelah 30 Desember 2025
- Termasuk tarball resmi, biner Visual Studio/MingW, paket NuGet, build untuk Android,
swift-sodium xcframework, Rust libsodium-sys-stable, dan libsodium.js
- Point release baru juga direncanakan
- Proyek ini dikelola oleh satu maintainer, dan peningkatan berkelanjutan dapat didukung melalui dukungan OpenCollective
1 komentar
Komentar Hacker News
Library PHP sodium_compat juga terdampak oleh masalah ini
Detail terkait bisa dilihat di security-advisories PR #756
Malam ini saya berencana memeriksa semua implementasi Ed25519 lain di ekosistem open source untuk memastikan apakah ada kelalaian verifikasi yang sama
Namun tidak ada kasus yang diimplementasikan dengan cara yang salah seperti kerentanan yang disebutkan di atas
Jika saya belum mengirim email, kemungkinan besar implementasi itu tidak ada di daftar deployment Ed25519 milik ianix, atau saya melewatkannya, atau implementasinya aman
Selama 4 bulan terakhir saya sedang mengembangkan binding sodium untuk Lean4
Sekarang saya sudah sampai pada tahap Ristretto255, dan saya jadi paham kenapa penulis begitu antusias terhadap teknologi ini
Ristretto adalah API canggih di atas Curve25519 yang memungkinkan penyusunan polinomial arbitrer, dan proses bereksperimen dengannya benar-benar menyenangkan
Jika penulis melihat tulisan ini, saya ingin menyampaikan terima kasih yang tulus
Tujuan Libsodium sejak awal adalah menyediakan API tingkat tinggi, bukan fungsi tingkat rendah
Library ini dirancang agar pengguna tidak perlu mengetahui algoritme internalnya, tetapi seiring waktu makin banyak kasus penggunaan yang langsung memakai fungsi tingkat rendah
Pada akhirnya Libsodium jadi digunakan seperti toolkit algoritme
Yang penting adalah menyadari ke mana arah yang diinginkan pengguna, dan tidak memaksakan proyek hanya ke satu cara tertentu
Beberapa proyek gagal karena menjadi terlalu dogmatis dalam hal seperti ini
Berbahaya jika non-ahli langsung menggunakan primitif kriptografi
Libsodium dirancang agar pengguna tidak menempatkan diri mereka sendiri dalam bahaya
Idealnya, library harus membuat penggunaan yang salah menjadi mustahil
Saya merekomendasikan tulisan terkait ini: “If You're Typing The Letters A-E-S Into Your Code, You're Doing It Wrong”
Karena itu, sering kali membatasi sebagian fitur sebagai private atau internal adalah pilihan yang tepat
Saya tidak yakin apakah Libsodium menarik batas itu dengan tepat, tetapi keseimbangan itu penting
Namun beberapa pengguna ternyata memakainya seperti batch runner
Saya memperbaiki beberapa bug untuk mendukung kebutuhan mereka
Pada akhirnya saya senang hanya karena ada orang yang menggunakannya
Bug kali ini adalah kesalahan verifikasi kriptografi yang halus tetapi penting
Pemeriksaan sederhana seperti “cek apakah ini valid” ternyata sebenarnya sangat kompleks
Jika titik di luar subgrup orde prima diizinkan, meskipun tampaknya tidak langsung menimbulkan kerentanan, hal itu bisa meruntuhkan asumsi pada lapisan di atasnya
Selain itu, primitif tingkat rendah sering dipakai ulang jauh lebih luas daripada yang dimaksudkan, jadi kelalaian verifikasi kecil bisa memiliki dampak besar
Masalah subgrup hanya muncul saat membangun protokol yang lebih kompleks di atas Curve25519
Karena itu saya selalu memetakan ulang semua titik ke subgrup orde prima sebisa mungkin
Monocypher punya fungsi-fungsi tingkat lanjut seperti ini
Misalnya fungsi seperti
crypto_x25519_dirty_fast()ataucrypto_elligator_map()Fungsi “dirty” seperti ini menghasilkan kunci publik yang mencakup seluruh kurva, sehingga tidak bisa dibedakan dari keacakan
Setelah itu, saat melakukan pertukaran kunci X25519, kita tetap bisa mendapatkan rahasia bersama yang sama
Ini dimungkinkan berkat desain DJB, karena meskipun kunci publiknya tidak normal, rahasia bersama tetap dipetakan ke subgrup orde prima
Pada akhirnya, Ristretto hanya diperlukan ketika pemetaan ulang seperti ini tidak memungkinkan
Tentu saja abstraksi grup orde prima itu berguna, tetapi jika seseorang mampu merancang protokol seperti itu, seharusnya ia juga mampu menangani cofactor yang tidak sepele
Jika Anda bekerja di perusahaan besar, saya sarankan mempertimbangkan untuk mendukung Frank di tingkat perusahaan
Kalaupun tahu, sepertinya saya harus mendukungnya dengan uang pribadi saya, bukan dari rekening perusahaan
Saya penasaran apakah libnacl juga terdampak
Saya setiap hari memakai perangkat lunak yang dikompilasi dengan libnacl, tetapi tidak ada yang dikompilasi dengan “libsodium”
Ini benar-benar library yang luar biasa
Saya ingin menyampaikan terima kasih kepada Frank Denis