---
title: Crypto API 与存储加密
url: https://doc.liz6.com/linux-kernel/09-security-mechanisms/03-crypto-api-and-storage-encryption
locale: zh
area: linux-kernel
tags:
- linux-kernel
- 安全机制
date: 2026-06-30
modified: 2026-06-30
description: '覆盖: Crypto API → dm-crypt/LUKS2 → fscrypt → WireGuard → kTLS → 硬件加速 → TPM 内核版本: 2.6 ~ 6.x'
---

# Crypto API 与存储加密

> 覆盖: Crypto API → dm-crypt/LUKS2 → fscrypt → WireGuard → kTLS → 硬件加速 → TPM
> 内核版本: 2.6 ~ 6.x

## Crypto API: 统一加密框架

```c
// crypto/ — 内核中所有加密操作的统一接口
// 支持同步和异步 (硬件加速器)

// 操作类:
struct crypto_skcipher  // 对称加密 (AES, ChaCha20)
struct crypto_aead       // AEAD (AES-GCM, ChaCha20-Poly1305)
struct crypto_shash      // 同步 hash (SHA-256, BLAKE2s)
struct crypto_ahash      // 异步 hash
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 header (前 16MB):
  - 加密算法: aes-xts-plain64, aes-cbc-essiv, ...
  - key slots (最多 8): 每 slot 含加密的主密钥 (由 passphrase/PKCS#11/tpm2 解锁)
  - PBKDF: argon2id (LUKS2, 抗 GPU/ASIC 攻击) 或 PBKDF2 (LUKS1)

数据路径:
  bio → scatter-gather list → crypto_skcipher → encrypt/decrypt per sector
    → 提交到下层块设备

加密模式: XTS (推荐), CBC-ESSIV (兼容)
```

## fscrypt: 文件系统原生加密

```c
// fs/crypto/
// 与 dm-crypt 的区别: 不是块设备级, 而是 per-file/per-directory
// 每个文件用自己的密钥 (由用户 master key + per-file nonce 派生)
// → 不同文件不同密钥 → 即使文件系统被 offline 读取, 也无法跨文件关联

// 支持: ext4, f2fs, UBIFS (Android)
// 使用: Android adoptable storage, Chrome OS user data

// ioctl 接口:
FS_IOC_SET_ENCRYPTION_POLICY  // 设目录的加密策略
FS_IOC_GET_ENCRYPTION_PWSALT  // 获取 per-directory salt
```

## WireGuard

```c
// drivers/net/wireguard/ (5.6+ 合入主线)
// 协议: Noise + ChaCha20-Poly1305 + Curve25519
// ~4000 行代码 → 安全审计可行

// 关键设计:
//   - 无连接: 收到有效包 → 自动建立会话
//   - 密钥轮换: Noise IK 握手 → 每 2 分钟轮换对称密钥
//   - 抗量子: 不重要 (Curve25519 是目前最优)

// 接口: 标准 network device + rtnetlink
wg-quick up wg0 → /etc/wireguard/wg0.conf
```

## kTLS (Kernel TLS, 4.13+)

```c
// 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 offload (Mellanox, Intel)
```

## 硬件加速

```
x86 AES-NI:     AES 指令集 → ~10x 加密速度
x86 CLMUL:      无进位乘法 (GCM 的 GHASH)
x86 SHA-NI:     SHA-1/SHA-256 硬件加速
ARMv8 CE:       Crypto Extensions (AES, SHA, GHASH)

内核自动选择: 有硬件加速器 → 使用加速 tfm → 软件 fallback
```

## TPM: 可信平台模块

```c
// drivers/char/tpm/
// TPM 2.0 (TPM 1.2 已废弃) → 安全密钥存储, 引导链测量, 远程认证

// 与 LUKS 集成:
//   TPM 存储 LUKS key → 仅在已知良性 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*
