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

Linux Crypto(2):使用者层-用户空间(AF_ALG、add_key()/request_key()/keyctl()等)

 

Linux Crypto 子系统为用户空间提供了丰富而强大的加密能力,主要通过以下接口实现:

接口类型主要作用用户空间工具内核对应模块典型使用场景
AF_ALG套接字 提供流式加密API OpenSSL (afalg引擎) crypto/af_alg.c 实时网络加密/文件流加密
Netlink接口 动态算法管理 cryptouser (自定义) crypto/crypto_user.c 算法加载/卸载/状态监控
/proc/crypto 算法信息查询 catgrep crypto/proc.c 系统诊断/算法选择
密钥系统调用 安全密钥管理 keyctl security/keys/ 加密卷密钥/安全启动密钥
设备映射ioctl 块设备加密管理 cryptsetup drivers/md/dm-ioctl.c 全盘加密/分区加密
dmsetup控制 底层设备映射操作 dmsetup drivers/md/dm-ioctl.c 高级存储配置/故障诊断
磁盘加密设备 透明块设备加密 cryptsetup open drivers/md/dm-crypt.c 加密卷日常访问

 

2 AF_ALG套接字接口

功能特性
1. 算法组合支持:支持模板语法如 cbc(aes)
2. 零拷贝优化:避免不必要的数据复制
3. 硬件加速透明:自动选择最优实现
4. 异步操作:最大化硬件利用率

af_alg_init
  ->proto_register--注册alg_proto协议结构体。
  ->sock_register--注册alg_family套接字协议族。
    ->alg_create--创建ALG套接字核心函数。
      ->sk_alloc--分配套接字内核对象,将具体的PF_ALG socket和alg_proto联系起来。
      ->sock_init_data--初始化套接字数据结构,其操作函数集为alg_proto_ops。
      ->alg_sock_destruct--定义套接字销毁回调。

alg_proto_ops定义了PF_ALG类型socket 系统调用的函数实现:

static const struct proto_ops alg_proto_ops = {
    .family        =    PF_ALG,                -- 协议族标识:ALG类型
    .owner        =    THIS_MODULE,            -- 模块所有者:当前模块

    .connect    =    sock_no_connect,        -- 禁用连接操作
    .socketpair    =    sock_no_socketpair,        -- 禁用socketpair创建
    .getname    =    sock_no_getname,        -- 禁用获取套接字名
    .ioctl        =    sock_no_ioctl,            -- 禁用ioctl控制
    .listen        =    sock_no_listen,            -- 禁用监听操作
    .shutdown    =    sock_no_shutdown,        -- 禁用关闭连接
    .mmap        =    sock_no_mmap,            -- 禁用内存映射
    .sendpage    =    sock_no_sendpage,        -- 禁用页面发送
    .sendmsg    =    sock_no_sendmsg,        -- 禁用消息发送
    .recvmsg    =    sock_no_recvmsg,        -- 禁用消息接收

    .bind        =    alg_bind,            -- 绑定加密算法到套接字
    .release    =    af_alg_release,            -- 释放套接字资源
    .setsockopt    =    alg_setsockopt,            -- 设置套接字选项
    .accept        =    alg_accept,            -- 接受算法会话请求
};

通过openssl使用AF_ALG进行测试:

# 1. 创建测试文件
dd if=/dev/urandom of=testfile bs=1M count=100

# 2. 使用AF_ALG加密
time openssl enc -aes-256-cbc -in testfile -out testfile.enc \
    -pass pass:test -md sha256 -engine afalg -pbkdf2 -iter 100000

# 3. 解密验证
time openssl enc -d -aes-256-cbc -in testfile.enc -out testfile.dec \
    -pass pass:test -md sha256 -engine afalg -pbkdf2 -iter 100000

# 4. 完整性检查
diff testfile testfile.dec && echo "加密/解密完整"

3 Netlink接口

netlink crypto_user 是 Linux 内核中用于加密子系统(Crypto API)的用户空间通信接口,基于 Netlink 协议实现。它允许用户空间程序动态查询、配置和管理内核中的加密算法(如 AES、SHA 等)。以下是其核心作用说明:

1. 算法查询
- 获取内核支持的加密算法列表(如 aes-cbc, sha256)。
- 查看算法详细信息(优先级、驱动名称、密钥长度等)。
2. 动态管理
- 添加/删除算法模板(如 cbc(aes))。
- 配置算法属性(如优先级调整)。
3. 状态监控
- 接收算法注册/注销的实时通知(通过 Netlink 多播组)。

crypto_user_init
  -> register_pernet_subsys -- 注册网络命名空间子系统
    -> crypto_netlink_net_ops -- 每个网络命名空间的初始化操作
      -> crypto_netlink_init -- 网络命名空间初始化函数
        -> netlink_kernel_create -- 创建内核级Netlink套接字
          [创建参数:]
            NETLINK_CRYPTO,       // 专用Netlink协议号
            crypto_netlink_rcv    // 接收回调函数
          ->crypto_netlink_rcv -- 核心接收函数
            -> netlink_rcv_skb -- Netlink消息处理框架
              -> crypto_user_rcv_msg -- 消息分发处理器
                -- 根据type找到对应消息类型的crypto_link处理函数
                [处理步骤:]
                1. netlink_dump_start -- 启动数据转储(批量查询)
                2. nlmsg_parse_deprecated -- 解析消息属性
                3. link->doit -- 执行具体操作

支持的类型包括:

enum {
    CRYPTO_MSG_BASE = 0x10,        // 消息类型起始值(避免与系统消息冲突)
    CRYPTO_MSG_NEWALG = 0x10,      // 注册新算法(如 cbc(aes))
    CRYPTO_MSG_DELALG,             // 删除算法(需管理员权限)
    CRYPTO_MSG_UPDATEALG,          // 更新算法属性(如优先级)
    CRYPTO_MSG_GETALG,             // 查询算法信息(最常用)
    CRYPTO_MSG_DELRNG,             // 删除随机数生成器(RNG)
    CRYPTO_MSG_GETSTAT,            // 获取加密子系统统计信息
    __CRYPTO_MSG_MAX               // 消息类型最大值(用于边界检查)
};

4 /proc/crypto

/proc/crypto 是 Linux 内核提供的一个虚拟文件,它不是一个独立的“项目”,而是 Linux 内核加密子系统 (crypto API) 的一个关键接口。它的主要作用是向用户空间(系统管理员、开发者、安全工具)动态展示当前正在运行的内核所支持的所有加密算法及其详细信息。

核心功能与作用:

1. 实时算法清单: 提供一份内核当前可用的所有加密算法、哈希算法、认证算法、随机数生成器(RNG)、压缩算法等的完整列表。这包括:

  • 对称密码: AES, DES, 3DES, ChaCha20, Salsa20, Serpent, Twofish, CAST5, Blowfish 等(包括 ECB, CBC, CTR, XTS, GCM, CCM 等多种模式)。
  • 非对称密码: RSA, DSA, ECDSA, DH, ECDH 等(通常由内核模块或硬件加速提供)。
  • 哈希函数: SHA-1, SHA-256, SHA-512, MD5, BLAKE2b/s, SM3 等。
  • 消息认证码: HMAC, CMAC, CBC-MAC, Poly1305 等。
  • 认证加密: AES-GCM, AES-CCM, ChaCha20-Poly1305 等(作为组合模式列出)。
  • 压缩算法: Deflate。
  • 随机数生成器: 如 stdrng (指向当前选择的默认 RNG), drbg_nopr_hmac_sha256 等。
  • 其他杂项: 如 ansi_cprng, jitterentropy_rng 等。

2. 算法详细信息: 对于列出的每个算法,/proc/crypto 提供了丰富的元数据,包括:

  • name: 算法的标准名称(例如 ctr(aes), sha256, ecb(des3_ede))。
  • driver: 实现该算法的具体内核驱动或模块(例如 aes-generic, aesni-intel, ccp, kernel 等)。这是识别算法是由软件(通用实现)、特定 CPU 指令集(如 AES-NI)还是专用硬件(如加密加速卡)实现的关键。
  • module: 提供该算法的内核模块名称(如果算法是模块化加载的)。
  • priority: 算法的优先级(数值)。当同一个算法有多个实现(如通用软件实现和硬件加速实现)时,内核会选择优先级最高的实现来使用。
  • refcnt: 引用计数,表示当前有多少用户(如 IPsec SA、dm-crypt 设备)正在使用该算法。
  • selftest: 算法是否通过了内核内置的自检 (passed)。
  • type: 算法类型(例如 skcipher, cipher, shash, ahash, akcipher, kpp, acomp, rng)。这决定了算法提供哪些操作接口。
  • blocksize: 算法的块大小(对于分组密码和哈希)。
  • digestsize: 哈希摘要的长度(对于哈希和 MAC)。
  • ivsize: 初始化向量 (IV) 的长度(对于需要 IV 的加密模式)。
  • seedsize: 种子长度(对于 DRBG)。
  • chunksize: 内部处理块大小(主要针对流式哈希/AHASH)。
  • key 相关信息: 最小/最大密钥长度、是否支持设置密钥 (setkey)。
  • async: 标志位,指示该算法实现是否支持异步操作(利用硬件加速时非常重要,允许加密操作不阻塞 CPU)。
  • internal: 标志位,指示该算法是否仅供内部使用(通常不可直接通过用户空间接口调用)。

5 密钥系统调用以及keyctl

密钥系统调用如下:

系统调用功能描述主要用途权限要求
add_key() 创建新密钥或密钥环 添加用户密钥、创建密钥环、存储加密密钥 对目标密钥环有write权限
request_key() 请求密钥(可触发用户空间协助) 动态获取加密密钥(如eCryptfs)、自动获取认证凭据 对目标密钥环有searchlink权限
keyctl() 密钥管理综合操作 更新/撤销/读取密钥、搜索密钥环、设置权限、密钥环管理 各子操作独立权限检查

keyctl命令使用这些系统调用进行密钥管理。

 

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

导航