Libsodiumの脆弱性
107日前原文(00f.net)
概要
- Libsodiumは13年の歴史を持つ暗号ライブラリ
- 高レベルAPI提供とAPIの後方互換性維持が特徴
- Ed25519関連の低レベル関数にバリデーション不備が発覚
- 影響範囲は一部の低レベル利用者のみ、高レベルAPI利用者は基本的に無関係
- Ristretto255利用やアップデート推奨、既に修正版が公開
Libsodiumの設計思想とAPIの歴史
- LibsodiumはDan Bernsteinの「暗号を簡単にする」という理念に基づいた設計
- 限定的で高レベルな関数・パラメータのみを公開、ユーザー向けの分かりやすいドキュメント作成
- 内部アルゴリズム非公開、ユーザーはアルゴリズム選択を意識せず利用可能
- APIの後方互換性を強く重視、API変更によるアプリ修正不要を目指す
- NaCl APIを継承しつつ、高レベル関数と一部低レベル関数も提供
低レベル関数利用の広がりと課題
- 年月と共にLibsodiumが低レベル暗号ツールキットとしても利用される傾向
- --enable-minimalビルドでのみ安定性保証、他の低レベルAPIは保証外
- カスタムプロトコル構築時、単一ライブラリで一貫したインターフェースが便利
- 多数のプラットフォーム・機能サポート維持、コミュニティ貢献のための努力
セキュリティ実績と新たなバグ発見
- 13年間CVEゼロの堅実なセキュリティ実績
- 最近のバッチ署名対応実験中、Ed25519点バリデーション関数の不備を発見
- crypto_core_ed25519_is_valid_point()で一部不正な点が許容されていた
技術的詳細とバグの内容
- Edwards25519曲線には複数の部分群(order)が存在
- 主部分群(order L)で暗号演算を実施
- 小さいorderや混合orderの点は排除すべき
- バリデーションは「点をL倍して単位元(X=0, Y=Z)になればOK」と設計
- 旧コードではX=0のみ確認し、Y=Zチェックが漏れていた
- そのため、X=0かつY≠Zな不正点も有効と誤判定
影響範囲
- 影響を受けるのは以下の場合
- バージョン1.0.20以前または2025年12月30日より前のリリース利用
- crypto_core_ed25519_is_valid_point()で外部入力点を検証
- Edwards25519上で独自暗号処理を実装
- 高レベルAPI(crypto_sign_*)は無関係
- crypto_scalarmult_ed25519によるスカラー乗算も安全
- 通常の鍵ペア生成関数は正しい部分群のみ利用
推奨対応・回避策
-
2019年導入のRistretto255を推奨、バリデーション不要・高速処理
-
ライブラリアップデートが困難な場合、下記Cコードでアプリ側回避可能
int is_on_main_subgroup(const unsigned char p[crypto_core_ed25519_BYTES]) { static const unsigned char L_1[crypto_core_ed25519_SCALARBYTES] = { ... }; static const unsigned char ID[crypto_core_ed25519_BYTES] = { ... }; unsigned char t[crypto_core_ed25519_BYTES]; unsigned char r[crypto_core_ed25519_BYTES]; if (crypto_scalarmult_ed25519_noclamp(t, L_1, p) != 0 || crypto_core_ed25519_add(r, t, p) != 0) { return 0; } return sodium_memcmp(r, ID, sizeof ID) == 0; }
修正版・今後のサポート
- 2025年12月30日以降の公式配布物・パッケージで修正済み
- Visual Studio, MingW, NuGet, swift-sodium, rust, libsodium.js等全プラットフォーム対応
- メンテナンスは個人の善意による無償提供、支援やスポンサー検討の呼びかけ
まとめと今後の利用指針
- Libsodiumは高い安全性と互換性を維持しつつ進化
- 低レベルAPI利用時のみ注意、基本的には高レベルAPI利用で安全
- Ristretto255への移行やライブラリアップデートが最善策
- オープンソース貢献・継続的なサポートのための支援重要