2 poin oleh GN⁺ 2026-01-01 | 1 komentar | Bagikan ke WhatsApp
  • 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

 
GN⁺ 2026-01-01
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

    • Saya menemukan bahwa di beberapa library, logika verifikasinya bahkan tidak ada sama sekali
      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
    • Saya ingin menyampaikan terima kasih karena telah berkontribusi pada open source
  • 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

    • Saya penasaran apakah ada repositori publik untuk proyek ini
  • 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

    • Poin yang menarik. Tapi sebaliknya, apa yang kita kira diinginkan pengguna bisa berbeda dari apa yang sebenarnya mereka butuhkan
      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”
    • Jika semua fungsi internal dianggap sebagai kontrak API, maka hampir setiap perubahan akan menjadi breaking change
      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
    • Dulu saya membuat framework pengujian C++ bernama CeeFIT, dan saya bangga karena bisa mendaftarkan fixture saat waktu kompilasi
      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

    • Namun X25519 dan Ed25519 sejak awal memang dirancang agar tidak memerlukan verifikasi semacam ini
      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() atau crypto_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

    • Saya bekerja di Apple, tetapi saya tidak tahu siapa Frank, dan juga tidak tahu prosedur sponsornya
      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