# 機能設計書 48-暗号化ライブラリ

## 概要

本ドキュメントは、FreeBSDにおける暗号化ライブラリ群（OpenSSLおよびカーネル暗号フレームワーク）の機能設計について記述する。ユーザ空間のOpenSSLライブラリとカーネル内のOCF（OpenBSD Cryptographic Framework）由来の暗号サブシステムを含む。

### 本機能の処理概要

FreeBSDの暗号化ライブラリは、ユーザ空間アプリケーション向けのOpenSSLライブラリと、カーネル内で動作するIPsec/GELI/ktls等が使用するカーネル暗号フレームワーク（opencrypto）の二層構成である。

**業務上の目的・背景**：ネットワーク通信の暗号化（TLS/SSL、IPsec）、ディスク暗号化（GELI）、デジタル署名、ハッシュ計算等、システムのあらゆるセキュリティ機能の暗号処理基盤として機能する。暗号化ライブラリの品質と性能はシステム全体のセキュリティとパフォーマンスに直接影響する。

**機能の利用シーン**：TLS/SSL通信の暗号化・復号化、X.509証明書の検証・生成、ハッシュ関数（SHA-256, SHA-512等）による完全性検証、HMAC/CMAC/GMAC等のメッセージ認証、AES/ChaCha20等の対称鍵暗号、RSA/ECDSA等の公開鍵暗号、カーネルTLS（ktls）オフロード、IPsecのパケット暗号化に使用される。

**主要な処理内容**：
1. ユーザ空間OpenSSLライブラリによる暗号処理（crypto/openssl/）
2. カーネル暗号フレームワーク（opencrypto）によるセッション管理
3. ハードウェア暗号アクセラレータ（cryptodev）の抽象化
4. ソフトウェア暗号実装（cryptosoft.c）
5. カーネルTLSオフロード（ktls_ocf.c）
6. 暗号アルゴリズム変換モジュール（xform_aes_cbc.c等）

**関連システム・外部連携**：IPsec（netipsec/）、GELI（geom/eli/）、ktls（kern/uipc_ktls.c）、OpenSSH（crypto/openssh/）、各種ネットワークプロトコルの暗号化処理。ハードウェアアクセラレータ（AES-NI、QAT等）との統合。

**権限による制御**：OpenSSLライブラリは一般ユーザプロセスから利用可能。カーネル暗号フレームワークはカーネル内のサブシステム（IPsec, GELI等）が直接利用する。/dev/cryptoデバイスを通じてユーザ空間からカーネル暗号機能にアクセス可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | （ライブラリのためGUI画面なし） | - | OpenSSL API / opencrypto API経由のプログラム利用 |

## 機能種別

暗号ライブラリ / 暗号フレームワーク / ハードウェアアクセラレータ抽象化

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| algorithm | int/string | Yes | 暗号アルゴリズム識別子 | サポートされたアルゴリズム |
| key | byte[] | Yes | 暗号鍵 | アルゴリズムに適合する鍵長 |
| iv | byte[] | No（アルゴリズム依存） | 初期化ベクトル | アルゴリズムに適合するIV長 |
| data | byte[] | Yes | 処理対象データ | 任意のバイト列 |
| operation | int | Yes | 暗号化/復号化/ハッシュ/署名等 | 有効な操作識別子 |

### 入力データソース

- アプリケーションコードからのAPI呼び出し
- カーネルサブシステムからのopencrypto API呼び出し
- /dev/crypto経由のユーザ空間リクエスト

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ciphertext | byte[] | 暗号化結果 |
| plaintext | byte[] | 復号化結果 |
| digest | byte[] | ハッシュ値 |
| signature | byte[] | デジタル署名 |
| mac | byte[] | メッセージ認証コード |

### 出力先

- 呼び出し元のバッファ
- mbuf（カーネル暗号処理の場合）

## 処理フロー

### 処理シーケンス

```
1. セッション確立（opencrypto）
   └─ crypto_newsession()でアルゴリズム・鍵・パラメータを設定
2. ドライバ選択
   └─ ハードウェアアクセラレータまたはソフトウェア実装を選択
3. 暗号操作リクエスト
   └─ crypto_dispatch()で暗号化/復号化/ハッシュ操作を投入
4. 処理実行
   └─ 選択されたドライバ（HW/SW）で暗号処理を実行
5. コールバック通知
   └─ crypto_done()で処理完了を通知
6. セッション解放
   └─ crypto_freesession()でリソース解放
```

### フローチャート

```mermaid
flowchart TD
    A[暗号操作要求] --> B[crypto_newsession]
    B --> C{HWアクセラレータ?}
    C -->|Yes| D[HWドライバ選択]
    C -->|No| E[ソフトウェア実装選択]
    D --> F[crypto_dispatch]
    E --> F
    F --> G[暗号処理実行]
    G --> H[crypto_done コールバック]
    H --> I[結果返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-48-01 | ドライバ優先順位 | ハードウェアアクセラレータが利用可能な場合はソフトウェア実装より優先 | セッション確立時 |
| BR-48-02 | フォールバック | ハードウェアドライバが失敗した場合はソフトウェア実装にフォールバック | 暗号操作失敗時 |
| BR-48-03 | 非同期処理 | カーネル暗号操作は非同期（コールバックベース）で実行可能 | opencrypto使用時 |

### 計算ロジック

- AES暗号化：128/192/256ビット鍵によるブロック暗号処理
- SHA-256/512：メッセージダイジェスト計算
- AEAD（認証付き暗号化）：AES-GCM, ChaCha20-Poly1305等の一体的暗号化+認証

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

### 操作別データベース影響一覧

本機能はデータベースを使用しない。暗号セッションとリクエストキューをカーネル内で管理する。

| 操作 | 対象データ構造 | 操作種別 | 概要 |
|-----|-------------|---------|------|
| newsession | crypto_session | CREATE | 暗号セッション作成 |
| dispatch | crypto_request | INSERT | 暗号操作リクエスト投入 |
| done | crypto_request | UPDATE | 操作完了通知 |
| freesession | crypto_session | DELETE | セッション解放 |

### テーブル別操作詳細

#### crypto_session

| 操作 | 項目 | 更新値・取得条件 | 備考 |
|-----|------|-----------------|------|
| CREATE | algorithm, key, driver | セッションパラメータ | ドライバ自動選択 |
| DELETE | session_id | セッション終了時 | 参照カウント管理 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| EINVAL | パラメータエラー | 不正なアルゴリズムまたは鍵長 | 正しいパラメータを指定 |
| ENOMEM | メモリ不足 | セッション/リクエスト割り当て失敗 | リソースを確保 |
| EOPNOTSUPP | 未サポート | 指定アルゴリズムの非サポート | サポートされたアルゴリズムを使用 |

### リトライ仕様

ハードウェアドライバの処理失敗時はソフトウェアドライバにフォールバックしてリトライする。

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

暗号操作はリクエスト単位で実行される。原子性はリクエスト単位で保証される。

## パフォーマンス要件

- AES-NIハードウェアアクセラレーションによる高速処理
- カーネル内のゼロコピー暗号処理（mbuf直接操作）
- マルチコアスケーラビリティ（ドライバの並列処理）

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

- 暗号鍵のメモリ上での保護（鍵がスワップに書き出されるリスク）
- サイドチャネル攻撃（タイミング攻撃等）への耐性
- 弱い暗号アルゴリズム（DES, RC4, MD5等）の非推奨化
- OpenSSLの脆弱性に対する迅速なパッチ適用
- /dev/cryptoデバイスのアクセス制御

## 備考

- opencryptoフレームワークはOpenBSD Cryptographic Framework（OCF）をベースにFreeBSD向けに大幅改修
- OpenSSLはcrypto/openssl/配下にソースツリーとして含まれる
- カーネルTLS（ktls）によりTLSレコード層の暗号処理をカーネル内でオフロード可能

---

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

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

### 推奨読解順序

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

カーネル暗号フレームワークのデータ構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | cryptodev.h | `sys/opencrypto/cryptodev.h` | crypto_session, crypto_op等の構造体定義。暗号アルゴリズム定数 |
| 1-2 | _cryptodev.h | `sys/opencrypto/_cryptodev.h` | ユーザ空間用暗号デバイスインタフェース定義 |

**読解のコツ**: opencryptoのAPIは「セッション」「リクエスト」「ドライバ」の3層構造。crypto_session_params構造体でアルゴリズムと鍵を指定し、cryptop構造体で個別の暗号操作を記述する。

#### Step 2: 暗号フレームワーク中核を理解する

セッション管理とリクエストディスパッチを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | crypto.c | `sys/opencrypto/crypto.c` | 暗号サブシステムの中核。OCF由来のフレームワーク（29-57行目のコメント参照）。crypto_newsession(), crypto_dispatch(), crypto_done()の実装 |

**主要処理フロー**:
1. **29-57行目**: OCFからの派生と大幅改修についてのコメント
2. crypto_newsession(): ドライバ選択とセッション確立
3. crypto_dispatch(): 暗号操作リクエストの投入
4. crypto_done(): 処理完了コールバック

#### Step 3: ソフトウェア暗号実装を理解する

ソフトウェアフォールバックの実装を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | cryptosoft.c | `sys/opencrypto/cryptosoft.c` | ソフトウェア暗号ドライバ。ハードウェアがない場合のフォールバック実装 |
| 3-2 | xform_aes_cbc.c | `sys/opencrypto/xform_aes_cbc.c` | AES-CBC変換モジュール |

#### Step 4: ユーザ空間デバイスインタフェースを理解する

/dev/crypto経由のユーザ空間アクセスを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | cryptodev.c | `sys/opencrypto/cryptodev.c` | /dev/cryptoデバイスドライバ。ユーザ空間からのioctl処理 |

#### Step 5: カーネルTLS統合を理解する

ktlsとopencryptoの連携を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | ktls_ocf.c | `sys/opencrypto/ktls_ocf.c` | カーネルTLSのopencrypto統合 |

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

```
ユーザ空間アプリケーション
    │
    ├─ OpenSSL API（libssl/libcrypto）
    │      └─ crypto/openssl/ ソースツリー
    │
    ├─ /dev/crypto → cryptodev.c
    │
カーネル空間:
    │
    ├─ crypto.c: 暗号フレームワーク中核
    │      ├─ crypto_newsession() → ドライバ選択
    │      ├─ crypto_dispatch() → リクエスト投入
    │      └─ crypto_done() → コールバック
    │
    ├─ ドライバ層:
    │      ├─ cryptosoft.c（ソフトウェア実装）
    │      │      ├─ xform_aes_cbc.c（AES-CBC）
    │      │      └─ その他xform_*.c
    │      └─ HWアクセラレータドライバ
    │
    └─ 利用者:
           ├─ IPsec（netipsec/）
           ├─ GELI（geom/eli/）
           └─ ktls（ktls_ocf.c）
```

### データフロー図

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

暗号操作リクエスト ──▶ crypto.c ────────────────▶ 暗号化/復号化結果
(IPsec/GELI/ktls)     ドライバ選択・ディスパッチ

OpenSSL API呼出 ───▶ libcrypto ──────────────▶ 暗号処理結果
(ユーザ空間)           ソフトウェア暗号実装

/dev/crypto ioctl ──▶ cryptodev.c ──────────▶ ユーザ空間結果
                      opencrypto フレームワーク
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| crypto.c | `sys/opencrypto/crypto.c` | ソース | 暗号フレームワーク中核 |
| cryptodev.h | `sys/opencrypto/cryptodev.h` | ヘッダ | 暗号デバイス・構造体定義 |
| cryptodev.c | `sys/opencrypto/cryptodev.c` | ソース | /dev/cryptoデバイスドライバ |
| cryptosoft.c | `sys/opencrypto/cryptosoft.c` | ソース | ソフトウェア暗号ドライバ |
| criov.c | `sys/opencrypto/criov.c` | ソース | I/Oベクトル暗号操作 |
| ktls_ocf.c | `sys/opencrypto/ktls_ocf.c` | ソース | カーネルTLS統合 |
| xform_aes_cbc.c | `sys/opencrypto/xform_aes_cbc.c` | ソース | AES-CBC変換モジュール |
| gmac.c | `sys/opencrypto/gmac.c` | ソース | GMAC実装 |
| gfmult.c | `sys/opencrypto/gfmult.c` | ソース | GF乗算（GCM用） |
| cbc_mac.c | `sys/opencrypto/cbc_mac.c` | ソース | CBC-MAC実装 |
| cryptodeflate.c | `sys/opencrypto/cryptodeflate.c` | ソース | 圧縮暗号 |
| openssl/ | `crypto/openssl/` | ソース | OpenSSLソースツリー |
