# 機能設計書 27-GEOM ELI（ディスク暗号化）

## 概要

本ドキュメントは、FreeBSDのGEOM ELIディスク暗号化機構の機能設計を記述する。GEOM ELIはGEOMフレームワーク上で動作するブロックレベルのディスク暗号化クラスであり、AES-XTSなどの暗号化アルゴリズムでディスクデータを透過的に暗号化・復号化する。

### 本機能の処理概要

**業務上の目的・背景**：ディスクの盗難や不正アクセスからデータを保護するために、ブロックデバイスレベルでの暗号化が必要。GEOM ELIはパーティション単位での暗号化を提供し、パスフレーズまたは鍵ファイルによる認証でデータを保護する。ブート前暗号化にも対応。

**機能の利用シーン**：ディスク全体暗号化（FDE）、パーティション暗号化、スワップパーティションの暗号化（ワンタイム鍵）、ZFSブートプールの暗号化。

**主要な処理内容**：
1. 暗号化プロバイダの初期化（geli init）とアタッチ（geli attach）
2. AES-XTS/AES-CBC等による透過的な暗号化・復号化
3. パスフレーズからの鍵導出（PKCS#5v2 PBKDF2）
4. 複数鍵スロットサポート
5. データ認証（HMAC、オプション）
6. ワンタイム鍵によるスワップ暗号化

**関連システム・外部連携**：GEOMストレージフレームワーク、OpenCrypto、crypto(9)フレームワーク

**権限による制御**：geli操作にはroot権限が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 16 | ZFSブート設定画面 | 補助機能 | ZFSプールのgeli暗号化オプション設定 |

## 機能種別

ストレージ暗号化 / データ保護

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| provider | char* | Yes | 暗号化対象デバイス | 有効なGEOMプロバイダ |
| passphrase | char* | Cond | パスフレーズ | 長さチェック |
| keyfile | char* | Cond | 鍵ファイル | ファイル存在チェック |
| aalgo | int | No | 認証アルゴリズム | サポート対象チェック |
| ealgo | int | Yes | 暗号化アルゴリズム | サポート対象チェック |
| keylen | int | Yes | 鍵長（ビット） | アルゴリズム制約 |
| sectorsize | int | No | セクタサイズ | 2の累乗 |

### 入力データソース

- gelibコマンドからの制御リクエスト（gctl）
- パスフレーズ（端末入力またはファイル）
- ディスク末尾に格納されたELIメタデータ

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| provider | g_provider* | 暗号化されたプロバイダ（.eliサフィックス付き） |
| 復号データ | void* | 透過的に復号されたブロックデータ |

### 出力先

- GEOMプロバイダとして上位層に公開（例: /dev/ada0p2.eli）

## 処理フロー

### 処理シーケンス

```
1. geli init（初期化）
   └─ ELIメタデータ生成
      ├─ マスター鍵生成（ランダム）
      ├─ PKCS#5v2 PBKDF2でパスフレーズから鍵導出
      ├─ マスター鍵の暗号化
      └─ メタデータをディスク末尾に書き込み
2. geli attach（アタッチ）
   └─ メタデータ読み込み
      ├─ パスフレーズ/鍵ファイルからマスター鍵復号
      ├─ データ暗号化鍵の生成
      └─ GEOMプロバイダ(.eli)作成
3. I/O処理
   └─ 書き込み: 平文データ → 暗号化 → 下位プロバイダへ
       読み込み: 下位プロバイダから → 復号 → 平文データ返却
4. geli detach（デタッチ）
   └─ 鍵の安全な消去 → GEOMプロバイダ破棄
```

### フローチャート

```mermaid
flowchart TD
    A[geli attach] --> B[メタデータ読み込み]
    B --> C[パスフレーズ/鍵ファイル検証]
    C --> D{認証成功?}
    D -->|Yes| E[マスター鍵復号]
    D -->|No| F[エラー: 認証失敗]
    E --> G[データ暗号化鍵生成]
    G --> H[.eliプロバイダ作成]
    H --> I[I/Oリクエスト待ち]
    I --> J{読み込み/書き込み?}
    J -->|Read| K[下位プロバイダから読み込み → 復号]
    J -->|Write| L[暗号化 → 下位プロバイダへ書き込み]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-27-01 | ワンタイム鍵 | G_ELI_FLAG_ONETIMEフラグでランダム鍵を使用（スワップ用） | フラグ指定時 |
| BR-27-02 | ブート対応 | G_ELI_FLAG_BOOTフラグでカーネルマウント前にパスフレーズ要求 | フラグ指定時 |
| BR-27-03 | デタッチポリシー | G_ELI_FLAG_WO_DETACH（書き込み後）/G_ELI_FLAG_RW_DETACH（最終クローズ後） | フラグ指定時 |
| BR-27-04 | 読み取り専用モード | G_ELI_FLAG_ROで書き込み拒否 | フラグ指定時 |
| BR-27-05 | BIO_DELETE制御 | G_ELI_FLAG_NODELETEでTRIM/DISCARD要求を通さない | フラグ指定時 |

### 計算ロジック

- 鍵導出: PKCS#5v2 PBKDF2 (パスフレーズ, ソルト, イテレーション) → 派生鍵
- IV生成: セクタオフセットから生成（v4以降はリトルエンディアン変換）
- データ暗号化鍵: マスター鍵から生成（v7以降はData Keyベース）

## データベース操作仕様

本機能はカーネル内ストレージ暗号化であり、RDBMS操作は行わない。

| 操作 | 対象データ構造 | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 初期化 | ELIメタデータ | CREATE | ディスク末尾にメタデータ書き込み |
| アタッチ | g_eli_softc | CREATE | 暗号化状態の初期化 |
| I/O | bio | READ/WRITE | 暗号化/復号処理 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| EINVAL | 不正パラメータ | 不正なメタデータまたはパラメータ | 設定を確認 |
| EPERM | 認証失敗 | パスフレーズ/鍵ファイルが不正 | 正しい認証情報を使用 |
| ENOENT | 未発見 | メタデータがディスク末尾に存在しない | geli initを実行 |

### リトライ仕様

パスフレーズ入力は通常3回まで再試行可能。

## トランザクション仕様

暗号化/復号は各BIOリクエスト単位で実行。セクタ単位の原子性はディスクデバイスに依存。鍵キャッシュ（g_eli_key_cache）によりホットキーを管理。

## パフォーマンス要件

- AES-NI等のハードウェアアクセラレーション活用（OpenCrypto経由）
- 鍵キャッシュによる鍵導出コスト削減
- マルチスレッド暗号化処理

## セキュリティ考慮事項

- 鍵の安全な消去（デタッチ時にメモリをゼロクリア）
- PKCS#5v2 PBKDF2による総当たり攻撃耐性
- データ認証オプション（G_ELI_FLAG_AUTH）による改竄検知
- バージョン履歴による後方互換性（現在v7）

## 備考

- Pawel Jakub Dawidekによる開発（2005-2019）
- サフィックス".eli"がプロバイダ名に付加される
- メタデータバージョン7が最新

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | g_eli.h | `sys/geom/eli/g_eli.h` | G_ELI_VERSION（76-84行目）バージョン管理、ON DISKフラグ（87-100行目）G_ELI_FLAG_ONETIME/BOOT/WO_DETACH等 |

**読解のコツ**: フラグ定義を理解することがELIの動作理解の鍵。ONETIME(スワップ用)、BOOT(ブート前認証)、AUTH(データ認証)の3つの主要用途を押さえる。バージョン履歴（62-75行目コメント）でIV生成方式や鍵管理の変遷を把握。

#### Step 2: メイン実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | g_eli.c | `sys/geom/eli/g_eli.c` | GEOMクラス登録、taste/attach/detach、BIO処理のエントリーポイント |

#### Step 3: 暗号化処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | g_eli_crypto.c | `sys/geom/eli/g_eli_crypto.c` | 暗号化/復号の実装 |
| 3-2 | g_eli_privacy.c | `sys/geom/eli/g_eli_privacy.c` | プライバシー（暗号化）処理 |
| 3-3 | g_eli_integrity.c | `sys/geom/eli/g_eli_integrity.c` | データ認証処理 |

#### Step 4: 鍵管理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | g_eli_key.c | `sys/geom/eli/g_eli_key.c` | マスター鍵・データ鍵管理 |
| 4-2 | g_eli_key_cache.c | `sys/geom/eli/g_eli_key_cache.c` | 鍵キャッシュ |
| 4-3 | pkcs5v2.c | `sys/geom/eli/pkcs5v2.c` | PKCS#5v2 PBKDF2鍵導出 |
| 4-4 | g_eli_hmac.c | `sys/geom/eli/g_eli_hmac.c` | HMAC計算 |

#### Step 5: 制御操作を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | g_eli_ctl.c | `sys/geom/eli/g_eli_ctl.c` | init/attach/detach/configure等のgctl操作 |

### プログラム呼び出し階層図

```
geli init (ユーザ空間)
    └─ g_eli_ctl.c: init処理
            +-- PKCS#5v2鍵導出 [pkcs5v2.c]
            +-- マスター鍵暗号化
            +-- メタデータ書き込み

geli attach (ユーザ空間)
    └─ g_eli_ctl.c: attach処理
            +-- メタデータ読み込み
            +-- パスフレーズ検証 [g_eli_hmac.c]
            +-- マスター鍵復号
            +-- g_eli_softc初期化
            +-- .eliプロバイダ作成

I/O処理
    └─ g_eli.c: start()
            +-- g_eli_privacy.c: 暗号化/復号
            |       +-- g_eli_crypto.c: OpenCrypto呼び出し
            +-- g_eli_integrity.c: データ認証（オプション）
            +-- g_eli_key.c: 鍵取得
            |       +-- g_eli_key_cache.c: キャッシュ検索
            +-- g_io_request(): 下位プロバイダへ
```

### データフロー図

```
[入力]                          [処理]                           [出力]

パスフレーズ/鍵ファイル ───▶ PKCS#5v2 PBKDF2        ───▶ 派生鍵
                              [pkcs5v2.c]                    │
                                                              ▼
ELIメタデータ          ───▶ マスター鍵復号           ───▶ データ暗号化鍵
(ディスク末尾)               [g_eli_key.c]

平文データ(Write)      ───▶ AES-XTS暗号化           ───▶ 暗号文
                              [g_eli_privacy.c]              (ディスクへ)

暗号文(Read)           ───▶ AES-XTS復号             ───▶ 平文データ
(ディスクから)               [g_eli_privacy.c]              (上位層へ)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| g_eli.h | `sys/geom/eli/g_eli.h` | ヘッダ | データ構造・フラグ・バージョン定義 |
| g_eli.c | `sys/geom/eli/g_eli.c` | ソース | GEOMクラス登録・BIOディスパッチ |
| g_eli_crypto.c | `sys/geom/eli/g_eli_crypto.c` | ソース | 暗号化/復号コア |
| g_eli_privacy.c | `sys/geom/eli/g_eli_privacy.c` | ソース | プライバシー処理 |
| g_eli_integrity.c | `sys/geom/eli/g_eli_integrity.c` | ソース | データ認証 |
| g_eli_key.c | `sys/geom/eli/g_eli_key.c` | ソース | 鍵管理 |
| g_eli_key_cache.c | `sys/geom/eli/g_eli_key_cache.c` | ソース | 鍵キャッシュ |
| g_eli_hmac.c | `sys/geom/eli/g_eli_hmac.c` | ソース | HMAC計算 |
| g_eli_ctl.c | `sys/geom/eli/g_eli_ctl.c` | ソース | gctl制御操作 |
| pkcs5v2.c | `sys/geom/eli/pkcs5v2.c` | ソース | PKCS#5v2鍵導出 |
| pkcs5v2.h | `sys/geom/eli/pkcs5v2.h` | ヘッダ | PKCS#5v2定義 |
