Crypto API - 3. 内核加密 API 架构

密码算法类型

内核加密 API 为以下密码类型提供不同的 API 调用:

  • 对称密码算法
  • AEAD密码算法
  • 消息摘要,包括带密钥的消息摘要
  • 随机数生成
  • 用户空间接口

加密和模板

内核加密API提供了单块密码和消息摘要的实现。此外,内核加密API还提供了许多“模板”,可与单块密码和消息摘要结合使用。模板包括所有类型的块链模式、HMAC机制等。

单块密码和消息摘要可以直接由调用者使用,或者与模板一起调用,形成多块密码或带密钥的消息摘要。

一个单一的块密码(A single block cipher)甚至可以使用多个模板进行调用。然而,不能在没有单一密码的情况下使用模板。

请参阅 /proc/crypto 并搜索“name”。例如:

  • aes
  • ecb(aes)
  • cmac(aes)
  • ccm(aes)
  • rfc4106(gcm(aes))
  • sha1
  • hmac(sha1)
  • authenc(hmac(sha1),cbc(aes))

在这些示例中,“aes”和“sha1”是密码,所有其他都是模板。

同步和异步操作

内核加密 API 提供同步和异步 API 操作。

使用同步 API 操作时,调用方调用由内核加密 API 同步执行的密码操作。这意味着,调用方将等待密码操作完成。因此,内核加密 API 调用的工作方式与常规函数调用类似。对于同步操作,API 调用集很小,在概念上与任何其他加密库相似。

异步操作由内核crypto API提供,这意味着对密码操作的调用几乎可以立即完成。该调用触发密码操作,但不发出完成的信号。在调用密码操作之前,调用者必须提供一个回调函数,内核crypto API可以调用该函数来发出密码操作完成的信号。此外,调用者必须通过对其数据应用适当的锁来确保能够处理此类异步事件。内核crypto API不会执行任何特殊的序列化操作来保护调用者的数据完整性。

加密 API 密码引用和优先级

密码由调用方使用字符串引用。该字符串具有以下语义:

template(single block cipher)

其中“template”和“single block cipher”分别是前述的模板和单个分组密码。如果适用,附加模板可以包含其他模板,例如

template1(template2(single block cipher)))

内核加密 API 可以提供模板或单个分组密码的多个实现。例如,较新的 Intel 硬件上的 AES 具有以下实现:AES-NI、汇编程序实现或直接 C。现在,当将字符串“aes”与内核加密 API 一起使用时,使用哪种密码实现?该问题的答案是内核加密 API 分配给每个密码实现的优先级编号。当调用方在密码句柄初始化期间使用字符串引用密码时,内核加密 API 会查找提供具有该名称的实现的所有实现,并选择具有最高优先级的实现。

现在,调用方可能需要引用特定的密码实现,因此不希望依赖基于优先级的选择。为了适应这种情况,内核加密 API 允许密码实现在公用名之外注册唯一名称。因此,使用该唯一名称时,调用方始终确保引用预期的密码实现。

可用密码列表在 /proc/crypto 中给出。但是,该列表并未指定模板和密码的所有可能排列。/proc/crypto 中列出的每个块都可能包含以下信息 – 如果下面列出的组件之一不适用于密码,则不会显示该组件:

name: the generic name of the cipher that is subject to the priority-based selection -- this name can be used by the cipher allocation 
API calls (all names listed above are examples for such generic names)

driver: the unique name of the cipher -- this name can be used by the cipher allocation API calls

module: the kernel module providing the cipher implementation (or "kernel" for statically linked ciphers)

priority: the priority value of the cipher implementation

refcnt: the reference count of the respective cipher (i.e. the number of current consumers of this cipher)

selftest: specification whether the self test for the cipher passed

type:

    skcipher for symmetric key ciphers

    cipher for single block ciphers that may be used with an additional template

    shash for synchronous message digest

    ahash for asynchronous message digest

    aead for AEAD cipher type

    compression for compression type transformations

    rng for random number generator

    kpp for a Key-agreement Protocol Primitive (KPP) cipher such as an ECDH or DH implementation

blocksize: blocksize of cipher in bytes

keysize: key size in bytes

ivsize: IV size in bytes

seedsize: required size of seed data for random number generator

digestsize: output size of the message digest

geniv: IV generator (obsolete)

密钥大小

分配密码句柄时,调用方仅指定密码类型。但是,对称密码通常支持多种密钥大小(例如 AES-128、AES-192 和 AES-256)。这些密钥大小由提供的密钥的长度决定。因此,内核加密 API 不提供选择特定对称密码密钥大小的单独方法。

密码分配类型和掩码

不同的密码句柄分配函数允许指定类型和掩码标志。这两个参数都具有以下含义(因此在后续部分中不介绍)。

type 标志指定密码算法的类型。当调用方需要默认处理时,调用方通常提供 0。否则,调用方可能会提供与上述密码类型匹配的以下选择:

CRYPTO_ALG_TYPE_CIPHER Single block cipher

CRYPTO_ALG_TYPE_COMPRESS Compression

CRYPTO_ALG_TYPE_AEAD Authenticated Encryption with Associated Data (MAC)

CRYPTO_ALG_TYPE_KPP Key-agreement Protocol Primitive (KPP) such as an ECDH or DH implementation

CRYPTO_ALG_TYPE_HASH Raw message digest

CRYPTO_ALG_TYPE_SHASH Synchronous multi-block hash

CRYPTO_ALG_TYPE_AHASH Asynchronous multi-block hash

CRYPTO_ALG_TYPE_RNG Random Number Generation

CRYPTO_ALG_TYPE_AKCIPHER Asymmetric cipher

CRYPTO_ALG_TYPE_PCOMPRESS Enhanced version of CRYPTO_ALG_TYPE_COMPRESS allowing for segmented compression / decompression 
instead of performing the operation on one segment only. CRYPTO_ALG_TYPE_PCOMPRESS is intended to replace 
CRYPTO_ALG_TYPE_COMPRESS once existing consumers are converted.

掩码标志限制密码的类型。唯一允许使用的标志是CRYPTO_ALG_ASYNC,用于将密码查找函数限制为异步密码。通常,调用者提供一个0作为掩码标志。

当调用方提供掩码和类型规范时,调用方会限制内核加密 API 可以执行的搜索,以便为给定的密码名称找到合适的密码实现。这意味着,即使调用方使用其初始化调用期间存在的密码名称,内核加密 API 也可能由于使用的类型和掩码字段而无法选择它。

内核加密 API 的内部结构

内核crypto API有一个内部结构,密码实现可以使用许多层和间接。本节将有助于阐明内核crypto API如何使用各种组件来实现完整的加密。

下面几节将根据现有的密码实现解释其内部结构。第一部分讨论最复杂的场景,其中所有其他场景构成一个逻辑子集。

通用AEAD密码结构

以下 ASCII art 分解了将 AEAD 密码与自动 IV 生成结合使用时的内核加密 API 层。所示示例由 IPSEC 层使用。

对于 AEAD 密码的其他用例,ASCII art也适用,但调用方不得将 AEAD 密码与单独的 IV 生成器一起使用。在这种情况下,调用方必须生成 IV。

所描述的示例基于通用 C 实现(gcm.c、aes-generic.c、ctr.c、ghash-generic.c、seqiv.c)分解了 GCM(AES) 的 AEAD 密码。通用实现用作显示内核加密 API 完整逻辑的示例。

一些简化的密码实现(如 AES-NI)可能提供了合并方面的实现,而这些方面在内核加密 API 看来不能再分解为层。在 AES-NI 实现的情况下,CTR 模式、GHASH 实现和 AES 密码都合并到一个注册到内核加密 API 的密码实现中。在这种情况下,以下 ASCII art所描述的概念也适用。但是,不再通过内核加密 API 将 GCM 分解为各个子组件。

以下 ASCII art中的每个块都是从内核加密 API 获取的独立密码实例。每个块都由调用方或其他块使用内核加密 API 为密码实现类型定义的 API 函数访问。

下面的块指示密码类型以及密码中实现的特定逻辑。

ASCII art图片还指示了调用结构,即谁调用了哪个组件。箭头指向调用的块,调用方在其中使用适用于为该块指定的密码类型的 API。

在这里插入图片描述

下面的调用序列适用于 IPSEC 层用 esp_output 函数触发加密操作。在配置过程中,管理员设置使用seqiv(rfc4106(gcm(aes)))作为ESP的密码。下面的调用序列现在在上面的ASCII图表中描述:

  1. esp_output() 调用 crypto_aead_encrypt() 以使用 IV 生成器触发 AEAD 密码的加密操作。

    SEQIV 生成 IV。

  2. 现在,SEQIV 使用 AEAD API 函数调用来调用关联的 AEAD 密码。在我们的例子中,在 SEQIV 的实例化过程中,GCM 的密码句柄被提供给 SEQIV。这意味着 SEQIV 使用 GCM 密码句柄调用 AEAD 密码操作。

    在实例化 GCM 句柄期间,将实例化 CTR(AES) 和 GHASH 密码。保留 CTR(AES) 和 GHASH 的密码句柄以供以后使用。

    GCM 实现负责以正确的方式调用 CTR 模式 AES 和 GHASH 密码,以实现 GCM 规范。

  3. GCM AEAD 密码类型实现现在使用实例化的 CTR(AES) 密码句柄调用 SKCIPHER API。

    在 CTR(AES) 密码的实例化过程中,将实例化 AES 的 CIPHER 类型实现。保留 AES 的密码句柄。

    这意味着 CTR(AES) 的 SKCIPHER 实现只实现了 CTR 块链模式。执行块链接操作后,将调用 AES 的 CIPHER 实现。

  4. CTR(AES) 的 SKCIPHER 现在使用 AES 密码句柄调用 CIPHER API 来加密一个块。

  5. GCM AEAD 实现还通过 AHASH API 调用 GHASH 密码实现。

当 IPSEC 层触发 esp_input() 函数时,遵循相同的调用序列,唯一的区别是操作从步骤 (2) 开始。

通用分组密码结构

通用分组密码遵循与上面 ASCII art图片所示相同的概念。

例如,CBC(AES) 是使用 cbc.c 和 aes-generic.c 实现的。上面的 ASCII art图片也适用,不同之处在于仅使用步骤 (4),SKCIPHER 块链接模式为 CBC

通用密码消息摘要结构

密码消息摘要实现再次遵循与上面 ASCII art图片中描述的相同概念。

例如,HMAC(SHA256) 是使用 hmac.c 和 sha256_generic.c 实现的。以下 ASCII art说明了实现:
在这里插入图片描述

当调用方触发HMAC操作时,调用顺序如下:

  1. AHASH API 函数由调用方调用。HMAC 实现根据需要执行其操作。

    在初始化 HMAC 密码期间,将实例化 SHA256 的 SHASH 密码类型。将保留 SHA256 实例的密码句柄。

    有时,HMAC 实现需要使用 SHA256 密码句柄的 SHA256 操作。

  2. HMAC 实例现在使用 SHA256 密码句柄调用 SHASH API 来计算消息摘要。

ref: https://www.kernel.org/doc/html/latest/crypto/architecture.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值