Skip to content

Linux 内核 Crypto 子系统异步加密机制分析 ​

目录 ​

  1. 概述
  2. AEAD 接口
  3. AHASH 接口
  4. SHASH 同步哈希接口
  5. 异步处理机制
  6. 哈希算法实现
  7. AEAD 算法实例
  8. 架构图

1. 概述 ​

Linux 内核 Crypto 子系统提供了两类加密接口:

类型描述特点
同步接口操作立即完成并返回结果简单直接,用于不需要并发的场景
异步接口通过回调机制通知完成支持硬件加速,适用于高性能场景

1.1 核心数据结构 ​

c
// include/linux/crypto.h:188-195
struct crypto_async_request {
    struct list_head list;           // 链表节点,用于请求队列
    crypto_completion_t complete;    // 完成回调函数指针
    void *data;                      // 用户数据指针
    struct crypto_tfm *tfm;          // 密码变换句柄
    u32 flags;                       // 标志位
};
c
// include/linux/crypto.h:179
typedef void (*crypto_completion_t)(void *req, int err);

1.2 异步等待机制 ​

c
// include/linux/crypto.h:363-367
struct crypto_wait {
    struct completion completion;     // 内核完成量
    int err;                         // 错误码
};

2. AEAD 接口 ​

AEAD (Authenticated Encryption with Associated Data) 提供带关联数据的认证加密,典型算法包括 GCM、CCM、ChaCha20-Poly1305。

2.1 AEAD 请求结构 ​

c
// include/crypto/aead.h:81-102
struct aead_request {
    struct crypto_async_request base;   // 基础异步请求

    unsigned int assoclen;               // 关联数据长度
    unsigned int cryptlen;               // 加密数据长度

    u8 *iv;                              // 初始化向量

    struct scatterlist *src;             // 源数据 scatter-gather 列表
    struct scatterlist *dst;             // 目标数据 scatter-gather 列表

    void *__ctx[] CRYPTO_MINALIGN_ATTR;  // 算法特定上下文
};

2.2 AEAD 算法定义 ​

c
// include/crypto/aead.h:105-153
struct aead_alg {
    int (*setkey)(struct crypto_aead *tfm, const u8 *key,
                  unsigned int keylen);      // 设置密钥
    int (*setauthsize)(struct crypto_aead *tfm, unsigned int authsize); // 设置认证标签大小
    int (*encrypt)(struct aead_request *req);  // 加密操作
    int (*decrypt)(struct aead_request *req);  // 解密操作
    int (*init)(struct crypto_aead *tfm);       // 初始化
    void (*exit)(struct crypto_aead *tfm);       // 退出清理

    unsigned int ivsize;                       // IV 大小
    unsigned int maxauthsize;                   // 最大认证标签大小
    unsigned int chunksize;                     // 块大小

    struct crypto_alg base;                     // 基础算法结构
};

2.3 AEAD 密码句柄 ​

c
// include/crypto/aead.h:155-160
struct crypto_aead {
    unsigned int authsize;     // 认证标签大小
    unsigned int reqsize;      // 请求上下文大小

    struct crypto_tfm base;    // 基础变换
};

2.4 crypto_alloc_aead() ​

c
// crypto/aead.c:201-204
struct crypto_aead *crypto_alloc_aead(const char *alg_name, u32 type, u32 mask)
{
    return crypto_alloc_tfm(alg_name, &crypto_aead_type, type, mask);
}

通过 crypto_alloc_tfm() 分配 AEAD 密码变换句柄,支持按名称查找算法。

2.5 aead_request_alloc() ​

c
// include/crypto/aead.h:518-529
static inline struct aead_request *aead_request_alloc(struct crypto_aead *tfm,
                                                      gfp_t gfp)
{
    struct aead_request *req;

    // 分配请求内存:请求结构 + 算法上下文
    req = kmalloc(sizeof(*req) + crypto_aead_reqsize(tfm), gfp);

    if (likely(req))
        aead_request_set_tfm(req, tfm);

    return req;
}

2.6 crypto_aead_encrypt() ​

c
// crypto/aead.c:84-92
int crypto_aead_encrypt(struct aead_request *req)
{
    struct crypto_aead *aead = crypto_aead_reqtfm(req);

    // 检查是否需要密钥
    if (crypto_aead_get_flags(aead) & CRYPTO_TFM_NEED_KEY)
        return -ENOKEY;

    // 调用算法特定的加密实现
    return crypto_aead_alg(aead)->encrypt(req);
}

2.7 crypto_aead_decrypt() ​

c
// crypto/aead.c:95-106
int crypto_aead_decrypt(struct aead_request *req)
{
    struct crypto_aead *aead = crypto_aead_reqtfm(req);

    if (crypto_aead_get_flags(aead) & CRYPTO_TFM_NEED_KEY)
        return -ENOKEY;

    // 解密时密文包含认证标签
    if (req->cryptlen < crypto_aead_authsize(aead))
        return -EINVAL;

    return crypto_aead_alg(aead)->decrypt(req);
}

3. AHASH 接口 ​

AHASH (Asynchronous Hash) 是异步哈希接口,支持 scatter-gather 列表输入。

3.1 AHASH 请求结构 ​

c
// include/crypto/hash.h:58-73
struct ahash_request {
    struct crypto_async_request base;   // 基础异步请求

    unsigned int nbytes;                // 数据长度
    union {
        struct scatterlist *src;        // scatter-gather 源
        const u8 *svirt;               // 或虚拟地址
    };
    u8 *result;                          // 摘要结果缓冲区

    struct scatterlist sg_head[2];       // scatter-gather 头
    crypto_completion_t saved_complete;  // 保存的回调
    void *saved_data;                    // 保存的用户数据

    void *__ctx[] CRYPTO_MINALIGN_ATTR; // 算法上下文
};

3.2 AHASH 算法定义 ​

c
// include/crypto/hash.h:154-171
struct ahash_alg {
    int (*init)(struct ahash_request *req);          // 初始化
    int (*update)(struct ahash_request *req);       // 更新数据
    int (*final)(struct ahash_request *req);         // 获取最终摘要
    int (*finup)(struct ahash_request *req);         // 更新+最终(组合操作)
    int (*digest)(struct ahash_request *req);        // 完整摘要计算
    int (*export)(struct ahash_request *req, void *out);  // 导出状态
    int (*import)(struct ahash_request *req, const void *in); // 导入状态
    int (*setkey)(struct crypto_ahash *tfm, const u8 *key, unsigned int keylen);

    struct hash_alg_common halg;                     // 通用哈希属性
};

3.3 AHASH 密码句柄 ​

c
// include/crypto/hash.h:277-282
struct crypto_ahash {
    bool using_shash;        // 是否使用底层 shash 算法
    unsigned int statesize;  // 状态大小
    unsigned int reqsize;    // 请求上下文大小
    struct crypto_tfm base;
};

3.4 crypto_alloc_ahash() ​

c
// crypto/ahash.c:841-845
struct crypto_ahash *crypto_alloc_ahash(const char *alg_name, u32 type, u32 mask)
{
    return crypto_alloc_tfm(alg_name, &crypto_ahash_type, type, mask);
}

3.5 ahash_request_alloc() ​

c
// include/crypto/hash.h:618-631
static inline struct ahash_request *ahash_request_alloc_noprof(
    struct crypto_ahash *tfm, gfp_t gfp)
{
    struct ahash_request *req;

    req = kmalloc_noprof(sizeof(struct ahash_request) +
                         crypto_ahash_reqsize(tfm), gfp);

    if (likely(req))
        ahash_request_set_tfm(req, tfm);

    return req;
}

3.6 crypto_ahash_digest() ​

c
// crypto/ahash.c:570-581
int crypto_ahash_digest(struct ahash_request *req)
{
    struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);

    // 如果底层使用 shash,直接调用 shash 的 digest
    if (likely(tfm->using_shash))
        return shash_ahash_digest(req, prepare_shash_desc(req, tfm));

    if (ahash_req_on_stack(req) && ahash_is_async(tfm))
        return -EAGAIN;
    if (crypto_ahash_get_flags(tfm) & CRYPTO_TFM_NEED_KEY)
        return -ENOKEY;

    return ahash_do_req_chain(req, &crypto_ahash_alg(tfm)->digest);
}

4. SHASH 同步哈希接口 ​

SHASH (Synchronous Hash) 是同步哈希接口,API 更简单但不支持真正的异步操作。

4.1 SHASH 描述符 ​

c
// include/crypto/hash.h:173-176
struct shash_desc {
    struct crypto_shash *tfm;    // 密码变换句柄
    void *__ctx[] __aligned(ARCH_SLAB_MINALIGN); // 算法上下文
};

4.2 SHASH 算法定义 ​

c
// include/crypto/hash.h:249-274
struct shash_alg {
    int (*init)(struct shash_desc *desc);
    int (*update)(struct shash_desc *desc, const u8 *data, unsigned int len);
    int (*final)(struct shash_desc *desc, u8 *out);
    int (*finup)(struct shash_desc *desc, const u8 *data, unsigned int len, u8 *out);
    int (*digest)(struct shash_desc *desc, const u8 *data, unsigned int len, u8 *out);
    int (*export)(struct shash_desc *desc, void *out);
    int (*import)(struct shash_desc *desc, const void *in);
    int (*setkey)(struct crypto_shash *tfm, const u8 *key, unsigned int keylen);

    unsigned int descsize;       // 描述符上下文大小

    union {
        struct HASH_ALG_COMMON;
        struct hash_alg_common halg;
    };
};

4.3 crypto_shash_digest() ​

c
// crypto/shash.c:183-194
int crypto_shash_digest(struct shash_desc *desc, const u8 *data,
                        unsigned int len, u8 *out)
{
    struct crypto_shash *tfm = desc->tfm;

    if (crypto_shash_get_flags(tfm) & CRYPTO_TFM_NEED_KEY)
        return -ENOKEY;

    return crypto_shash_op_and_zero(crypto_shash_alg(tfm)->digest, desc,
                                    data, len, out);
}

5. 异步处理机制 ​

5.1 crypto_wait 等待机制 ​

c
// include/linux/crypto.h:372-374
#define DECLARE_CRYPTO_WAIT(_wait) \
    struct crypto_wait _wait = { \
        COMPLETION_INITIALIZER_ONSTACK((_wait).completion), 0 }

// crypto/api.c:704-713
void crypto_req_done(void *data, int err)
{
    struct crypto_wait *wait = data;

    if (err == -EINPROGRESS)
        return;

    wait->err = err;
    complete(&wait->completion);
}

// include/linux/crypto.h:381-393
static inline int crypto_wait_req(int err, struct crypto_wait *wait)
{
    switch (err) {
    case -EINPROGRESS:
    case -EBUSY:
        wait_for_completion(&wait->completion);
        reinit_completion(&wait->completion);
        err = wait->err;
        break;
    }
    return err;
}

5.2 异步操作流程 ​

用户空间
    │
    ▼
┌─────────────────────────────────────────┐
│ 1. 分配请求: aead_request_alloc()       │
└─────────────────────────────────────────┘
    │
    ▼
┌─────────────────────────────────────────┐
│ 2. 设置回调: aead_request_set_callback() │
│    - complete = crypto_req_done        │
│    - data = &wait                       │
└─────────────────────────────────────────┘
    │
    ▼
┌─────────────────────────────────────────┐
│ 3. 设置数据: aead_request_set_crypt()    │
└─────────────────────────────────────────┘
    │
    ▼
┌─────────────────────────────────────────┐
│ 4. 发起操作: crypto_aead_encrypt()       │
└─────────────────────────────────────────┘
    │
    ▼
┌─────────────────────────────────────────┐
│ 5. 返回 -EINPROGRESS (硬件队列已满)      │
└─────────────────────────────────────────┘
    │
    ▼
┌─────────────────────────────────────────┐
│ 6. 等待: crypto_wait_req()              │
│    - wait_for_completion()              │
└─────────────────────────────────────────┘
    │
    ▼
┌─────────────────────────────────────────┐
│ 7. 硬件完成后调用 crypto_req_done()      │
│    - complete() 唤醒等待进程             │
└─────────────────────────────────────────┘
    │
    ▼
用户空间继续执行

5.3 回调保存与恢复机制 ​

AHASH 使用保存/恢复机制来链接多个异步操作:

c
// crypto/ahash.c:391-397
static void ahash_save_req(struct ahash_request *req, crypto_completion_t cplt)
{
    req->saved_complete = req->base.complete;  // 保存原始回调
    req->saved_data = req->base.data;         // 保存原始数据
    req->base.complete = cplt;                 // 设置新回调
    req->base.data = req;                      // 设置新数据
}

static void ahash_restore_req(struct ahash_request *req)
{
    req->base.complete = req->saved_complete;  // 恢复原始回调
    req->base.data = req->saved_data;         // 恢复原始数据
}

5.4 请求链机制 ​

c
// crypto/ahash.c:322-369
static int ahash_do_req_chain(struct ahash_request *req,
                              int (*const *op)(struct ahash_request *req))
{
    struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);

    // 虚拟地址请求或非虚拟请求直接执行
    if (crypto_ahash_req_virt(tfm) || !ahash_request_isvirt(req))
        return (*op)(req);

    // 需要 fallback 的情况处理状态导出/导入
    if (crypto_ahash_need_fallback(tfm))
        return -ENOSYS;

    // 执行链式操作
    {
        u8 state[HASH_MAX_STATESIZE];

        if (op == &crypto_ahash_alg(tfm)->digest) {
            ahash_request_set_tfm(req, crypto_ahash_fb(tfm));
            err = crypto_ahash_digest(req);
            goto out_no_state;
        }

        err = crypto_ahash_export(req, state);
        ahash_request_set_tfm(req, crypto_ahash_fb(tfm));
        err = err ?: crypto_ahash_import(req, state);

        if (op == &crypto_ahash_alg(tfm)->finup) {
            err = err ?: crypto_ahash_finup(req);
            goto out_no_state;
        }

        err = err ?:
              crypto_ahash_update(req) ?:
              crypto_ahash_export(req, state);

        ahash_request_set_tfm(req, tfm);
        return err ?: crypto_ahash_import(req, state);
    }
}

6. 哈希算法实现 ​

6.1 MD5 算法注册 ​

c
// crypto/md5.c:177-216
static struct shash_alg algs[] = {
    {
        .base.cra_name        = "md5",
        .base.cra_driver_name = "md5-lib",
        .base.cra_priority    = 300,
        .base.cra_blocksize   = MD5_BLOCK_SIZE,
        .base.cra_module      = THIS_MODULE,
        .digestsize           = MD5_DIGEST_SIZE,
        .init                 = crypto_md5_init,
        .update               = crypto_md5_update,
        .final                = crypto_md5_final,
        .digest               = crypto_md5_digest,
        .export               = crypto_md5_export,
        .import               = crypto_md5_import,
        .descsize             = sizeof(struct md5_ctx),
        .statesize            = MD5_SHASH_STATE_SIZE,
    },
    // ... HMAC-MD5 算法
};

6.2 SHA256 算法注册 ​

c
// crypto/sha256.c:318-395
static struct shash_alg algs[] = {
    {
        .base.cra_name        = "sha256",
        .base.cra_driver_name = "sha256-lib",
        .base.cra_priority    = 300,
        .base.cra_blocksize   = SHA256_BLOCK_SIZE,
        .base.cra_module      = THIS_MODULE,
        .digestsize           = SHA256_DIGEST_SIZE,
        .init                 = crypto_sha256_init,
        .update               = crypto_sha256_update,
        .final                = crypto_sha256_final,
        .digest               = crypto_sha256_digest,
        .descsize             = sizeof(struct sha256_ctx),
        .statesize            = SHA256_SHASH_STATE_SIZE,
    },
    // ... SHA224, HMAC-SHA224, HMAC-SHA256
};

6.3 摘要计算流程 ​

                    ┌─────────────────────────────────────────┐
                    │        crypto_ahash_digest()            │
                    │         (AHASH 异步接口)                 │
                    └─────────────────────────────────────────┘
                                      │
                    ┌─────────────────┴─────────────────┐
                    │                                   │
                    ▼                                   ▼
         ┌──────────────────┐               ┌──────────────────┐
         │  using_shash=true │               │ using_shash=false│
         └──────────────────┘               └──────────────────┘
                    │                                   │
                    ▼                                   ▼
    ┌───────────────────────────┐       ┌───────────────────────────┐
    │   shash_ahash_digest()    │       │  ahash_do_req_chain()    │
    │   (crypto/ahash.c:205)    │       │    状态链式处理           │
    └───────────────────────────┘       └───────────────────────────┘
                    │                                   │
                    ▼                                   ▼
    ┌───────────────────────────┐       ┌───────────────────────────┐
    │  crypto_shash_digest()    │       │  algorithm->digest()     │
    │   (crypto/shash.c:183)    │       │   异步硬件操作            │
    └───────────────────────────┘       └───────────────────────────┘
                    │                                   │
                    └─────────────────┬─────────────────┘
                                      ▼
                    ┌───────────────────────────────────┐
                    │      回调链完成或同步返回           │
                    └───────────────────────────────────┘

6.4 状态导出/导入机制 ​

哈希算法支持暂停和恢复计算:

c
// 导出状态
int crypto_ahash_export(struct ahash_request *req, void *out)
{
    struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);

    if (likely(tfm->using_shash))
        return crypto_shash_export(ahash_request_ctx(req), out);

    // ... 非 shash 情况处理
}

// 导入状态
int crypto_ahash_import(struct ahash_request *req, const void *in)
{
    struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);

    if (likely(tfm->using_shash))
        return crypto_shash_import(prepare_shash_desc(req, tfm), in);

    // ... 非 shash 情况处理
}

7. AEAD 算法实例 ​

7.1 GCM 加密流程 ​

GCM (Galois/Counter Mode) 是典型的 AEAD 算法:

c
// crypto/gcm.c:445-456
static int crypto_gcm_encrypt(struct aead_request *req)
{
    struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req);
    struct skcipher_request *skreq = &pctx->u.skreq;
    u32 flags = aead_request_flags(req);

    crypto_gcm_init_common(req);
    crypto_gcm_init_crypt(req, req->cryptlen);
    skcipher_request_set_callback(skreq, flags, gcm_encrypt_done, req);

    return crypto_skcipher_encrypt(skreq) ?:
           gcm_encrypt_continue(req, flags);
}

GCM 加密流程图 ​

                    ┌─────────────────────────────────────────┐
                    │         crypto_gcm_encrypt()            │
                    └─────────────────────────────────────────┘
                                      │
                    ┌─────────────────┴─────────────────┐
                    ▼                                   ▼
        ┌───────────────────────┐           ┌───────────────────────┐
        │  CTR 模式加密数据      │           │  初始化 GHASH          │
        │  (skcipher)          │           │  (ahash)              │
        └───────────────────────┘           └───────────────────────┘
                    │                                   │
                    └─────────────────┬─────────────────┘
                                      ▼
                    ┌─────────────────────────────────────────┐
                    │           GHASH 计算关联数据             │
                    └─────────────────────────────────────────┘
                                      │
                                      ▼
                    ┌─────────────────────────────────────────┐
                    │           生成认证标签                   │
                    │    auth_tag = GHASH(ciphertext || len)  │
                    └─────────────────────────────────────────┘
                                      │
                                      ▼
                    ┌─────────────────────────────────────────┐
                    │        拼接: ciphertext || tag          │
                    └─────────────────────────────────────────┘

GCM 异步回调链 ​

c
// crypto/gcm.c:430-443
static void gcm_encrypt_done(void *data, int err)
{
    struct aead_request *req = data;

    if (err)
        goto out;

    // 继续执行 gcm_encrypt_continue
    err = gcm_encrypt_continue(req, 0);
    if (err == -EINPROGRESS)
        return;

out:
    aead_request_complete(req, err);
}

// crypto/gcm.c:418-428
static int gcm_encrypt_continue(struct aead_request *req, u32 flags)
{
    struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req);
    struct crypto_gcm_ghash_ctx *gctx = &pctx->ghash_ctx;

    gctx->src = sg_next(req->src == req->dst ? pctx->src : pctx->dst);
    gctx->cryptlen = req->cryptlen;
    gctx->complete = gcm_enc_copy_hash;  // 设置完成回调

    return gcm_hash(req, flags);  // 启动哈希操作
}

7.2 ChaCha20-Poly1305 加密 ​

ChaCha20-Poly1305 是另一种 AEAD 算法:

c
// crypto/chacha20poly1305.c:272-285
static int chachapoly_encrypt(struct aead_request *req)
{
    struct chachapoly_req_ctx *rctx = aead_request_ctx(req);

    rctx->cryptlen = req->cryptlen;
    rctx->flags = aead_request_flags(req);

    /* 加密调用链:
     * - chacha_encrypt/done()
     * - poly_genkey/done()
     * - poly_hash()
     */
    return chacha_encrypt(req);
}

ChaCha20-Poly1305 加密流程 ​

                    ┌─────────────────────────────────────────┐
                    │       chachapoly_encrypt()             │
                    └─────────────────────────────────────────┘
                                      │
                                      ▼
                    ┌─────────────────────────────────────────┐
                    │         chacha_encrypt()                │
                    │   使用 ChaCha20 加密数据                 │
                    └─────────────────────────────────────────┘
                                      │
                    ┌─────────────────┴─────────────────┐
                    ▼                                   ▼
        ┌───────────────────────┐           ┌───────────────────────┐
        │   加密完成回调        │           │   poly_genkey()       │
        │   chacha_encrypt_done │           │   生成 Poly1305 密钥  │
        └───────────────────────┘           └───────────────────────┘
                    │                                   │
                    └─────────────────┬─────────────────┘
                                      ▼
                    ┌─────────────────────────────────────────┐
                    │           poly_hash()                  │
                    │   使用 Poly1305 计算认证标签             │
                    └─────────────────────────────────────────┘
                                      │
                                      ▼
                    ┌─────────────────────────────────────────┐
                    │   拼接: ciphertext || auth_tag          │
                    └─────────────────────────────────────────┘

异步回调继续机制 ​

c
// crypto/chacha20poly1305.c:56-68
static inline void async_done_continue(struct aead_request *req, int err,
                                       int (*cont)(struct aead_request *))
{
    if (!err) {
        struct chachapoly_req_ctx *rctx = aead_request_ctx(req);

        rctx->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
        err = cont(req);  // 调用下一个操作
    }

    // 如果不是正在处理中,则完成请求
    if (err != -EINPROGRESS && err != -EBUSY)
        aead_request_complete(req, err);
}

8. 架构图 ​

8.1 Crypto API 层次结构 ​

┌─────────────────────────────────────────────────────────────────────────┐
│                           用户空间 API                                  │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐   │
│  │   AEAD      │  │   AHASH     │  │   SHASH     │  │   SKCIPHER  │   │
│  │  认证加密   │  │  异步哈希   │  │  同步哈希   │  │  对称密钥   │   │
│  └─────────────┘  └─────────────┘  └─────────────┘  └─────────────┘   │
└─────────────────────────────────────────────────────────────────────────┘
                                    │
                                    ▼
┌─────────────────────────────────────────────────────────────────────────┐
│                         通用 Crypto API                                 │
│  ┌─────────────────────────────────────────────────────────────────┐   │
│  │  crypto_alloc_aead() / crypto_alloc_ahash() / crypto_alloc_*   │   │
│  │  aead_request_alloc() / ahash_request_alloc()                   │   │
│  │  crypto_wait_req() / crypto_req_done()                          │   │
│  └─────────────────────────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────────────────────────┘
                                    │
                                    ▼
┌─────────────────────────────────────────────────────────────────────────┐
│                        算法类型层                                      │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐   │
│  │   GCM       │  │  ChaCha20   │  │    MD5      │  │   SHA-256   │   │
│  │             │  │ -Poly1305   │  │             │  │             │   │
│  └─────────────┘  └─────────────┘  └─────────────┘  └─────────────┘   │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐   │
│  │    CCM      │  │    CBC      │  │    CRC32    │  │   AES       │   │
│  │             │  │             │  │             │  │             │   │
│  └─────────────┘  └─────────────┘  └─────────────┘  └─────────────┘   │
└─────────────────────────────────────────────────────────────────────────┘
                                    │
                                    ▼
┌─────────────────────────────────────────────────────────────────────────┐
│                        驱动/硬件层                                     │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐   │
│  │  软件实现   │  │  CPU 指令   │  │  硬件引擎   │  │   外部模块  │   │
│  │  (generic) │  │  (AES-NI)   │  │  (crypto    │  │  (PKCS#11)  │   │
│  │             │  │             │  │   engine)   │  │             │   │
│  └─────────────┘  └─────────────┘  └─────────────┘  └─────────────┘   │
└─────────────────────────────────────────────────────────────────────────┘

8.2 AEAD 数据流 ​

输入数据:
┌─────────────────────────────────────────────────────────────────────────┐
│  assoc_data (关联数据)  │  plaintext (明文)                             │
└─────────────────────────────────────────────────────────────────────────┘

AEAD 加密:
┌─────────────────────────────────────────────────────────────────────────┐
│                              AEAD 加密引擎                             │
│  ┌─────────────────┐    ┌─────────────────┐    ┌─────────────────┐     │
│  │   关联数据      │───▶│   加密操作      │───▶│   生成认证标签   │     │
│  │   (不做修改)    │    │  (CTR/GCM 等)   │    │   (Poly1305/    │     │
│  │                 │    │                 │    │    GHASH)       │     │
│  └─────────────────┘    └─────────────────┘    └─────────────────┘     │
│                                    │                      │             │
└────────────────────────────────────┼──────────────────────┼─────────────┘
                                     ▼                      ▼
输出数据:
┌─────────────────────────────────────────────────────────────────────────┐
│  assoc_data (关联数据)  │  ciphertext (密文)  │  auth_tag (认证标签)      │
└─────────────────────────────────────────────────────────────────────────┘

8.3 异步请求状态机 ​

                    ┌─────────────────────────────────────────┐
                    │              请求分配                   │
                    │   aead_request_alloc() / ahash_*       │
                    └─────────────────────────────────────────┘
                                      │
                                      ▼
                    ┌─────────────────────────────────────────┐
                    │            设置回调                     │
                    │   aead_request_set_callback(req,       │
                    │              complete, data)            │
                    └─────────────────────────────────────────┘
                                      │
                                      ▼
                    ┌─────────────────────────────────────────┐
                    │           发起异步操作                   │
                    │   crypto_aead_encrypt(req)               │
                    │   或 crypto_ahash_digest(req)            │
                    └─────────────────────────────────────────┘
                                      │
                         ┌────────────┴────────────┐
                         │                         │
                         ▼                         ▼
              ┌────────────────────┐    ┌────────────────────┐
              │  返回 0 (同步完成) │    │ 返回 -EINPROGRESS  │
              │                    │    │   (异步处理中)     │
              └────────────────────┘    └────────────────────┘
                                                 │
                                                 ▼
                                    ┌─────────────────────────┐
                                    │    硬件/软件处理中      │
                                    │                         │
                                    │  可能多次回调:          │
                                    │  done1 → done2 → done3 │
                                    └─────────────────────────┘
                                                 │
                                                 ▼
                                    ┌─────────────────────────┐
                                    │   crypto_req_done()    │
                                    │   complete() 被调用    │
                                    │   唤醒等待进程         │
                                    └─────────────────────────┘
                                                 │
                                                 ▼
                                    ┌─────────────────────────┐
                                    │   crypto_wait_req()    │
                                    │   返回最终结果          │
                                    └─────────────────────────┘

8.4 AHASH 与 SHASH 关系 ​

┌─────────────────────────────────────────────────────────────────────────┐
│                           AHASH (异步)                                  │
│  ┌─────────────────────────────────────────────────────────────────┐   │
│  │                        crypto_ahash_*                           │   │
│  │  ┌───────────┐  ┌───────────┐  ┌───────────┐  ┌───────────┐    │   │
│  │  │   init    │  │  update   │  │   final   │  │  digest   │    │   │
│  │  └───────────┘  └───────────┘  └───────────┘  └───────────┘    │   │
│  │                         │                                       │   │
│  │            ┌─────────────┴─────────────┐                         │   │
│  │            ▼                           ▼                         │   │
│  │  ┌─────────────────────┐    ┌─────────────────────┐             │   │
│  │  │   using_shash=true  │    │  using_shash=false  │             │   │
│  │  │   (底层同步实现)     │    │  (原生异步实现)     │             │   │
│  │  └─────────────────────┘    └─────────────────────┘             │   │
│  └─────────────────────────────────────────────────────────────────┘   │
│                                    │                                   │
└────────────────────────────────────┼───────────────────────────────────┘
                                     ▼
┌─────────────────────────────────────────────────────────────────────────┐
│                           SHASH (同步)                                  │
│  ┌─────────────────────────────────────────────────────────────────┐   │
│  │                        crypto_shash_*                          │   │
│  │  ┌───────────┐  ┌───────────┐  ┌───────────┐  ┌───────────┐    │   │
│  │  │   init    │  │  update   │  │   final   │  │  digest   │    │   │
│  │  └───────────┘  └───────────┘  └───────────┘  └───────────┘    │   │
│  │                                                                 │   │
│  │  ┌─────────────────────────────────────────────────────────┐   │   │
│  │  │              直接调用算法实现 (同步)                      │   │   │
│  │  └─────────────────────────────────────────────────────────┘   │   │
│  └─────────────────────────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────────────────────────┘

附录: 关键 API 速查表 ​

AEAD API ​

函数文件:行号说明
crypto_alloc_aead()crypto/aead.c:201分配 AEAD 句柄
crypto_free_aead()include/crypto/aead.h:216释放 AEAD 句柄
crypto_aead_setkey()crypto/aead.c:44设置密钥
crypto_aead_setauthsize()crypto/aead.c:65设置认证标签大小
crypto_aead_encrypt()crypto/aead.c:84加密
crypto_aead_decrypt()crypto/aead.c:95解密
aead_request_alloc()include/crypto/aead.h:518分配请求
aead_request_free()include/crypto/aead.h:535释放请求
aead_request_set_callback()include/crypto/aead.h:565设置回调
aead_request_set_crypt()include/crypto/aead.h:605设置加密数据
aead_request_set_ad()include/crypto/aead.h:624设置关联数据

AHASH API ​

函数文件:行号说明
crypto_alloc_ahash()crypto/ahash.c:841分配 AHASH 句柄
crypto_free_ahash()include/crypto/hash.h:338释放 AHASH 句柄
crypto_ahash_setkey()crypto/ahash.c:290设置密钥
crypto_ahash_digest()crypto/ahash.c:570计算摘要
crypto_ahash_init()crypto/ahash.c:371初始化
crypto_ahash_update()crypto/ahash.c:447更新数据
crypto_ahash_finup()crypto/ahash.c:528更新并获取结果
crypto_ahash_final()include/crypto/hash.h:510获取最终结果
ahash_request_alloc()include/crypto/hash.h:618分配请求
ahash_request_free()include/crypto/hash.h:637释放请求
ahash_request_set_callback()include/crypto/hash.h:676设置回调
ahash_request_set_crypt()include/crypto/hash.h:699设置数据

SHASH API ​

函数文件:行号说明
crypto_alloc_shash()crypto/shash.c:385分配 SHASH 句柄
crypto_free_shash()include/crypto/hash.h:777释放 SHASH 句柄
crypto_shash_setkey()crypto/shash.c:50设置密钥
crypto_shash_digest()crypto/shash.c:183计算摘要
crypto_shash_init()crypto/shash.c:81初始化
crypto_shash_update()include/crypto/hash.h:1003更新数据
crypto_shash_final()include/crypto/hash.h:1023获取结果
crypto_shash_tfm_digest()crypto/shash.c:196使用 tfm 直接计算摘要

异步等待 API ​

函数文件:行号说明
DECLARE_CRYPTO_WAIT()include/linux/crypto.h:372声明等待变量
crypto_init_wait()include/linux/crypto.h:395初始化等待
crypto_wait_req()include/linux/crypto.h:381等待请求完成
crypto_req_done()crypto/api.c:704请求完成回调

文档版本: 1.0生成日期: 2026-04-26源码版本: Linux Kernel (最新 master 分支)

基于 VitePress 构建