LXR | KVM | PM | Time | Interrupt | Systems Performance | Bootup Optimization

Linux Crypto(6):akcipher以及rsa、rsa,sha256算法注册

1 akcipher 在内核 Crypto 框架中的位置

Crypto 框架层级:
1. 用户层 (AF_ALG, /dev/crypto, 内核子系统)
2. Crypto 核心引擎层 (算法管理, 请求调度)
3. 算法实现层 (软件实现/硬件驱动)

akcipher是 Linux 内核 Crypto 框架中用于非对称加密算法的抽象,处于 Crypto API 的算法实现层。akcipher 为 RSA、ECDSA、SM2 等非对称算法提供统一接口,支持:

- 公钥加密/私钥解密
- 数字签名生成/验证
- 密钥交换操作

2 关键数据结构

数据结构之间关系:

 

struct akcipher_alg定义非对称算法的具体实现,包含算法操作函数指针和基本属性。

struct akcipher_alg {
    // 核心操作函数
    int (*encrypt)(struct akcipher_request *req);      // 公钥加密
    int (*decrypt)(struct akcipher_request *req);      // 私钥解密
    int (*sign)(struct akcipher_request *req);         // 签名生成
    int (*verify)(struct akcipher_request *req);       // 签名验证
    
    // 密钥管理
    int (*set_pub_key)(struct crypto_akcipher *tfm,   // 设置公钥
                      const void *key, unsigned int keylen);
    int (*set_priv_key)(struct crypto_akcipher *tfm,  // 设置私钥
                       const void *key, unsigned int keylen);
    
    // 算法属性
    unsigned int (*max_size)(struct crypto_akcipher *tfm); // 最大数据长度
    
    // 生命周期管理
    int (*init)(struct crypto_akcipher *tfm);         // 算法实例初始化
    void (*exit)(struct crypto_akcipher *tfm);        // 算法实例清理
    
    // 基础算法描述(关键!)
    struct crypto_alg base;  // 包含以下重要成员:
        char *cra_name;      // 算法名 (e.g., "rsa")
        char *cra_driver_name; // 驱动名 (e.g., "rsa-caam")
        unsigned int cra_priority; // 优先级 (硬件>300, 软件100)
        struct module *cra_module; // 所属模块 (THIS_MODULE)
        unsigned int cra_ctxsize;  // 私有上下文大小
        int (*cra_init)(struct crypto_tfm *tfm); // 全局初始化
        void (*cra_exit)(struct crypto_tfm *tfm); // 全局清理
};

struct akcipher_request封装单次非对称操作的上下文和数据。

struct akcipher_request {
    // 异步请求基础
    struct crypto_async_request base;  // 包含:
        struct list_head list;         // 请求队列指针
        void (*complete)(...);         // 完成回调函数
        void *data;                    // 回调数据
        u32 flags;                     // 标志位 (e.g., CRYPTO_TFM_REQ_MAY_BACKLOG)
    
      // 关联对象
      struct crypto_akcipher *tfm;       // 关联的算法实例
    
    // 数据描述
    struct scatterlist *src;           // 输入数据分散表
    struct scatterlist *dst;           // 输出数据分散表
    unsigned int src_len;              // 输入数据长度
    unsigned int dst_len;              // 输出缓冲区长度
    
    // 操作私有上下文
    void *__ctx[];  // 零长度数组,实际大小由 akcipher_alg.base.cra_ctxsize 决定
};

struct akcipher_instance用于通过模板创建算法实例(如复合算法 rsa-pkcs1v15)。

struct akcipher_instance {
// 模板特定数据
    union {
        struct {
            char head[CRYPTO_MAX_ALG_NAME]; // 内部头信息
            struct crypto_instance base; // 子算法生成器
        } s;
        struct akcipher_alg alg;   // 内联算法实现
    } __ctx;
    
    // 析构函数
    void (*free)(struct akcipher_instance *inst);
};

3 核心API

1. 算法管理

int crypto_register_akcipher(struct akcipher_alg *alg);
void crypto_unregister_akcipher(struct akcipher_alg *alg);

2. 算法实例管理

struct crypto_akcipher *crypto_alloc_akcipher(const char *alg_name, u32 type, u32 mask);
void crypto_free_akcipher(struct crypto_akcipher *tfm);

3. 密钥管理

int crypto_akcipher_set_pub_key(struct crypto_akcipher *tfm, const void *key, unsigned int keylen);
int crypto_akcipher_set_priv_key(struct crypto_akcipher *tfm, const void *key, unsigned int keylen);

4. 请求管理

struct akcipher_request *akcipher_request_alloc(struct crypto_akcipher *tfm, gfp_t gfp);
void akcipher_request_free(struct akcipher_request *req);
void akcipher_request_set_callback(struct akcipher_request *req, u32 flgs, 
                                  crypto_completion_t cmpl, void *data);
void akcipher_request_set_crypt(struct akcipher_request *req,
                               struct scatterlist *src, struct scatterlist *dst,
                               unsigned int src_len, unsigned int dst_len);

5. 操作执行

int crypto_akcipher_encrypt(struct akcipher_request *req);  // 公钥加密
int crypto_akcipher_decrypt(struct akcipher_request *req);  // 私钥解密
int crypto_akcipher_sign(struct akcipher_request *req);     // 数字签名
int crypto_akcipher_verify(struct akcipher_request *req);   // 签名验证

6. 辅助函数

unsigned int crypto_akcipher_maxsize(struct crypto_akcipher *tfm);
void *akcipher_request_ctx(struct akcipher_request *req);  // 获取请求上下文

4 RSA算法注册

rsa_init注册了rsa算法,并注册了一个模版用于创建基于rsa的符合算法rsa,sha256:

rsa_init
  ->crypto_register_akcipher--注册基础rsa算法实现。
  ->crypto_register_template--注册PKCS#1填充的算法模版rsa_pkcs1pad_tmpl到crypto_template_list。

 上述创建的算法可以通过/proc/crypto查看:

name         : pkcs1pad(rsa,sha256)
driver       : pkcs1pad(rsa-generic,sha256)
module       : kernel
priority     : 100
refcnt       : 1
selftest     : passed
internal     : no
type         : akcipher

name         : rsa
driver       : rsa-generic
module       : kernel
priority     : 100
refcnt       : 1
selftest     : passed
internal     : no
type         : akcipher

 rsa对应的算法实现如下:

static struct akcipher_alg rsa = {
        .encrypt = rsa_enc,
        .decrypt = rsa_dec,
        .set_priv_key = rsa_set_priv_key,
        .set_pub_key = rsa_set_pub_key,
        .max_size = rsa_max_size,
        .exit = rsa_exit_tfm,
        .base = {
                .cra_name = "rsa",
                .cra_driver_name = "rsa-generic",
                .cra_priority = 100,
                .cra_module = THIS_MODULE,
                .cra_ctxsize = sizeof(struct rsa_mpi_key),
        },
};

当用户请求pkcs1pad(rsa,sha256)类算法时,调用pkcs1pad_create用于创建一个模版实例:

pkcs1pad_create
  ->crypto_check_attr_type--验证算法属性类型是否有效。
  ->akcipher_instance_ctx--获取模板实例的私有上下文。
  ->crypto_grap_akcipher--获取基础 RSA 算法引用。
  ->crypto_spawn_akcipher_alg--生成基础算法实例(如 "rsa")。
  ->akcipher_register_instance--将新创建的复合算法注册到内核。

新创建的符合算法的操作函数为:

.init = pkcs1pad_init,             // 实例初始化
.exit = pkcs1pad_exit,             // 实例清理

.set_pub_key = pkcs1pad_set_pub_key,  // 设置公钥(透传到底层)
.set_priv_key = pkcs1pad_set_priv_key,// 设置私钥(透传到底层)

.encrypt = pkcs1pad_encrypt,       // 填充后加密
.decrypt = pkcs1pad_decrypt,       // 解密后验证填充
.sign = pkcs1pad_sign,             // 填充后签名
.verify = pkcs1pad_verify,         // 验证填充签名

.max_size = pkcs1pad_max_size,      // 计算最大数据长度

rsa_pkcs1pad_tmpl模版的struct akciphe_alg实例:

pkcs1pad_set_pub_key设置公钥:

pkcs1pad_set_pub_key
  ->akcipher_tfm_ctx
  ->crypto_akcipher_set_pub_key
  ->crypto_akcipher_maxsize

以pkcs1pad_verify进行验签:

pkcs1pad_verify
  ->pkcs1pad_sg_set_buf
  ->akcipher_request_set_tfm
  ->akcipher_request_set_callback
    ->pkcs1pad_verify_complete
  ->akcipher_request_set_crypt
  ->crypto_akcipher_encrypt
    ->调用基础akcipher的encrypt()函数。比如rsa的rsa_enc。   
->pkcs1pad_verify_complete     ->sg_pcopy_to_buffer

 

posted on 2025-07-25 23:59  ArnoldLu  阅读(174)  评论(0)    收藏  举报

导航