このページの目次

Crypto API とストレージ暗号化

階層: Crypto API → dm-crypt/LUKS2 → fscrypt → WireGuard → kTLS → ハードウェアアクセラレーション → TPM カーネルバージョン: 2.6 ~ 6.x

Crypto API: 統一された暗号化フレームワーク

// crypto/ — カーネル内の全暗号化操作に対する統一インターフェース
// 同期および非同期 (ハードウェアアクセラレータ) をサポート

// 操作タイプ:
struct crypto_skcipher  // 対称暗号 (AES, ChaCha20)
struct crypto_aead       // AEAD (AES-GCM, ChaCha20-Poly1305)
struct crypto_shash      // 同期ハッシュ (SHA-256, BLAKE2s)
struct crypto_ahash      // 非同期ハッシュ
struct crypto_rng        // 擬似乱数生成器
struct crypto_akcipher   // 非対称暗号 (RSA, ECDH)
struct crypto_kpp        // 鍵共有 (DH, ECDH)

// 使用手順:
tfm = crypto_alloc_skcipher("cbc(aes)", 0, 0);
crypto_skcipher_setkey(tfm, key, keylen);
crypto_skcipher_encrypt(tfm, src, dst, len);
crypto_free_skcipher(tfm);

dm-crypt / LUKS2

dm-crypt: ブロックデバイスレベルの透過的暗号化 (bio とブロックデバイスの間に暗号化層を挿入)
LUKS2: dm-crypt の鍵管理およびメタデータ形式

LUKS ヘッダー (先頭 16MB):
  - 暗号アルゴリズム: aes-xts-plain64, aes-cbc-essiv, ...
  - 鍵スロット (最大 8): 各スロットには、パスフレーズ/PKCS#11/tpm2 によって解除される暗号化済みマスターキーを含む
  - PBKDF: argon2id (LUKS2、GPU/ASIC 攻撃耐性) または PBKDF2 (LUKS1)

データパス:
  bio → スキャター・ギャザーリスト → crypto_skcipher → セクターごとの暗号化/復号
    → 下位ブロックデバイスへの送信

暗号化モード: XTS (推奨), CBC-ESSIV (互換性用)

fscrypt: ファイルシステムネイティブ暗号化

// fs/crypto/
// dm-crypt との違い: ブロックデバイスレベルではなく、ファイル/ディレクトリ単位
// 各ファイルは独自のキーを使用 (ユーザーマスターキー + ファイル固有のノンスから派生)
// → ファイルごとに異なるキー → ファイルシステムがオフラインで読み取られても、ファイル間で関連付けられない

// サポート: ext4, f2fs, UBIFS (Android)
// 使用例: Android のアダプタブルストレージ、Chrome OS のユーザーデータ

// ioctl インターフェース:
FS_IOC_SET_ENCRYPTION_POLICY  // ディレクトリの暗号化ポリシーを設定
FS_IOC_GET_ENCRYPTION_PWSALT  // ディレクトリ固有のソルトを取得

WireGuard

// drivers/net/wireguard/ (5.6 以降メインラインにマージ)
// プロトコル: Noise + ChaCha20-Poly1305 + Curve25519
// コード行数は約 4000 行 → セキュリティ監査が現実的

// 重要な設計:
//   - コネクションレス: 有効なパケットを受信すると、自動的にセッションが確立される
//   - 鍵ローテーション: Noise IK ハンドシェイク → 対称鍵を 2 分ごとにローテーション
//   - 耐量子性: 重要ではない (Curve25519 が現時点で最良)

// インターフェース: 標準的なネットワークデバイス + rtnetlink
wg-quick up wg0 → /etc/wireguard/wg0.conf

kTLS (Kernel TLS, 4.13 以降)

// net/tls/
// TLS レコード層をカーネルに移動 → ユーザー空間での sendfile などのゼロコピー操作で TLS を利用可能
// シナリオ: HTTPS プロキシ (nginx/haproxy)、ファイルサーバー

setsockopt(fd, SOL_TLS, TLS_TX, &crypto_info, sizeof(crypto_info));
// → カーネルが対称暗号化を管理 → sendfile() で直接暗号化して送信

// サポート: TLS 1.2 (AES-GCM), TLS 1.3 (AES-GCM, ChaCha20-Poly1305)
// ハードウェアオフロード: kTLS オフロードに対応する NIC (Mellanox, Intel)

ハードウェアアクセラレーション

x86 AES-NI:     AES 命令セット → 暗号化速度が約 10 倍
x86 CLMUL:      キャリーレス乗算 (GCM の GHASH 用)
x86 SHA-NI:     SHA-1/SHA-256 のハードウェアアクセラレーション
ARMv8 CE:       Crypto Extensions (AES, SHA, GHASH)

カーネルの自動選択: ハードウェアアクセラレータがある場合 → アクセラレータ用 tfm を使用 → ソフトウェアフォールバック

TPM: 信頼できるプラットフォームモジュール

// drivers/char/tpm/
// TPM 2.0 (TPM 1.2 は廃止) → 安全な鍵の保存、ブートチェーンの測定、リモートアテステーション

// LUKS との統合:
//   TPM が LUKS キーを保存 → 既知の良性な PCR 値の場合のみキーを解放 (systemd-cryptenroll)
//   改ざんされたカーネル → PCR 値が変化 → TPM がキーの解放を拒否 → ディスクが読み取不可

参考

  • ソースコード⁠: crypto/, drivers/md/dm-crypt.c, fs/crypto/, drivers/net/wireguard/, net/tls/, drivers/char/tpm/
  • カーネルドキュメント⁠: Documentation/crypto/, Documentation/filesystems/fscrypt.rst

キーワード: Crypto API, dm-crypt, LUKS2, fscrypt, WireGuard, kTLS, AES-NI, TPM