Crypto API - 9.1 编程接口-块密码算法定义
编程接口-块密码算法定义
这些数据结构定义了模块化加密算法实现,通过 crypto_register_alg() 和 crypto_unregister_alg() 进行管理。
struct cipher_alg
single-block symmetric ciphers definition(单块对称密码定义)
定义:
struct cipher_alg {
unsigned int cia_min_keysize;
unsigned int cia_max_keysize;
int (*cia_setkey)(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen);
void (*cia_encrypt)(struct crypto_tfm *tfm, u8 *dst, const u8 *src);
void (*cia_decrypt)(struct crypto_tfm *tfm, u8 *dst, const u8 *src);
};
成员
cia_min_keysize
变换所支持的最小密钥长度。这是此变换算法支持的最小密钥长度。此值必须设置为预定义值之一,因为它不是特定于硬件的。此字段的可能取值可以通过 git grep "_MIN_KEY_SIZE" include/crypto/ 找到。
cia_max_keysize
变换所支持的最大密钥长度。这是此变换算法支持的最大密钥长度。此值必须设置为预定义值之一,因为它不是特定于硬件的。此字段的可能取值可以通过 git grep "_MAX_KEY_SIZE" include/crypto/ 找到。
cia_setkey
为变换设置密钥。此函数用于将提供的密钥编程到硬件中,或将密钥存储在变换上下文中以供稍后编程。请注意,此函数确实会修改变换上下文。在变换对象存在期间,可以多次调用此函数,因此必须确保密钥已正确地重新编程到硬件中。此函数还负责检查密钥长度的有效性。
cia_encrypt
对单个块进行加密。此函数用于加密一个大小必须为cra_blocksize的数据块。它始终对整个cra_blocksize进行操作,不可能加密一个更小尺寸的块。因此,提供的缓冲区的大小也必须至少为cra_blocksize。输入和输出缓冲区始终对齐到cra_alignmask。如果由crypto API的用户提供的输入或输出缓冲区之一不对齐到cra_alignmask,crypto API将重新对齐缓冲区。重新对齐意味着将分配一个新的缓冲区,数据将被复制到新的缓冲区中,然后在新的缓冲区上进行处理,然后将数据复制回原始缓冲区,最后释放新的缓冲区。如果在cra_init调用中实施了软件回退(fallback),当算法不支持所有密钥长度时,此函数可能需要使用回退。如果密钥存储在变换上下文中,此函数可能需要将密钥重新编程到硬件中。此函数不应修改变换上下文,因为可能会并行调用相同的变换对象。
cia_decrypt
解密单个块。这与cia_encrypt相反,条件完全相同。
描述
所有字段都是强制性的,必须填写。
struct compress_alg
compression/decompression algorithm(压缩/解压缩算法)
定义
struct compress_alg {
int (*coa_compress)(struct crypto_tfm *tfm, const u8 *src, unsigned int slen, u8 *dst, unsigned int *dlen);
int (*coa_decompress)(struct crypto_tfm *tfm, const u8 *src, unsigned int slen, u8 *dst, unsigned int *dlen);
};
成员
coa_compress
压缩指定长度的缓冲区,将生成的数据存储在指定的缓冲区中。数据的长度以 dlen 返回。
coa_decompress
解压缩源缓冲区,将未压缩的数据存储在指定的缓冲区中。数据的长度以 dlen 返回。
描述
所有字段都是强制性的
struct crypto_alg
definition of a cryptograpic cipher algorithm(加密密码算法的定义)
定义:
struct crypto_alg {
struct list_head cra_list;
struct list_head cra_users;
u32 cra_flags;
unsigned int cra_blocksize;
unsigned int cra_ctxsize;
unsigned int cra_alignmask;
int cra_priority;
refcount_t cra_refcnt;
char cra_name[CRYPTO_MAX_ALG_NAME];
char cra_driver_name[CRYPTO_MAX_ALG_NAME];
const struct crypto_type *cra_type;
union {
struct cipher_alg cipher;
struct compress_alg compress;
} cra_u;
int (*cra_init)(struct crypto_tfm *tfm);
void (*cra_exit)(struct crypto_tfm *tfm);
void (*cra_destroy)(struct crypto_alg *alg);
struct module *cra_module;
};
成员
cra_list
内部使用
ra_users
内部使用
cra_flags
描述此变换的标志。请参见include/linux/crypto.h CRYPTO_ALG_*标志,用于精细调整变换算法的描述。
cra_blocksize
此变换的最小块大小。以字节为单位表示该算法可以转换的最小单位的大小。用户必须遵守此值。在HASH变换的情况下,可以传递比cra_blocksize更小的块到加密API进行变换,而在其他任何变换类型的情况下,任何尝试转换小于cra_blocksize的块都将返回错误。
cra_ctxsize
转换的操作上下文的大小。此值通知内核加密 API 需要为转换上下文分配的内存大小。
cra_alignmask
对于 cipher、skcipher、lskcipher 和 aead 算法,这比算法实现对输入和输出缓冲区所需的对齐方式(以字节为单位)少 1。当使用未与此对齐方式对齐的缓冲区调用加密 API 时,加密 API 会自动利用适当对齐的临时缓冲区来符合算法的需求。(对于散点列表(scatterlists),仅当算法使用 skcipher_walk 帮助程序函数时才会发生这种情况。这种错位处理会带来性能损失,因此算法最好不要设置非零对齐掩码。此外,加密 API 用户可能希望分配与所用算法的对齐掩码对齐的缓冲区,以避免 API 必须重新对齐它们。注意:哈希算法不支持对齐掩码,并且它们始终为 0。
cra_priority
此转换实现的优先级。如果 Crypto API 可以使用具有相同cra_name的多个转换,内核将使用具有最高cra_priority的转换。
cra_refcnt
内部使用
cra_name
变换算法的通用名称(可由多个实现使用)。这是变换本身的名称。内核在查找特定变换的提供者时使用此字段。
cra_driver_name
变换提供者的唯一名称。这是变换提供者的名称。它可以是任意值,但通常情况下,它包含芯片或提供者的名称以及变换算法的名称。
cra_type
加密转换的类型。这是指向struct crypto_type的指针,该指针实现了所有转换类型通用的回调函数。有多种选项,例如crypto_skcipher_type,crypto_ahash_type,crypto_rng_type。这个字段可能为空。在这种情况下,没有通用的回调函数。这是密码、压缩、散列等算法的情况。
cra_u
实现变换的回调函数。这是多个结构的联合体。根据上述 cra_type 和 cra_flags 选择的变换类型,必须填充相关的结构体回调函数。这个字段可能为空。这是散列算法的情况。
cra_u.cipher
联合体成员,包含单块对称密码定义。请参阅 struct cipher_alg。
cra_u.compress
包含(解)压缩算法的联合成员。请参阅 struct compress_alg。
cra_init
初始化加密变换对象。此函数用于初始化加密变换对象。该函数在实例化时仅被调用一次,在分配变换上下文之后立即调用。如果加密硬件具有一些需要软件处理的特殊要求,此函数应检查变换的精确要求,并采取任何软件回退措施。
cra_exit
取消初始化加密变换对象。这是 cra_init 的对应函数,用于移除 cra_init 中设置的各种更改。
cra_destroy
内部使用。
cra_module
此转换实现的所有者。设置为 THIS_MODULE。
描述
struct crypto_alg 描述了一个通用的 Crypto API 算法,对于所有的变换都是通用的。在此未记录的任何变量都不应该被密码实现使用,因为它们是 Crypto API 内部使用的。
对称密钥密码 API
对称密钥密码 API 用于 CRYPTO_ALG_TYPE_SKCIPHER 类型的密码(在 /proc/crypto 中被列为 “skcipher” 类型)。
异步密码操作意味着密码请求的函数调用会立即返回,而不等待操作完成。该密码请求会作为一个独立的内核线程进行调度,通过进程调度程序在不同的 CPU 上进行负载平衡。为了让内核加密 API 能够通知调用者密码请求的完成,调用者必须提供一个回调函数。当请求完成时,该函数会使用密码句柄进行调用。
为了支持异步操作,除了仅仅提供密码句柄,还必须向内核加密 API 提供其他的信息。这些额外的信息通过填充 skcipher_request 数据结构来提供。
对于对称密钥密码 API,状态是通过 tfm 密码句柄来维护的。一个 tfm 可以在多个调用和并行操作中使用。对于异步块密码调用,除了用于密码请求的 IV 之外,还可以将供调用者使用的上下文数据引用到请求数据结构中。对于加密驱动程序实施者来说,维护这种状态信息是很重要的,因为当在加密操作完成时调用回调函数时,如果它并行调用了多个操作,那么回调函数可能需要一些关于刚刚完成的操作的信息。这种状态信息由内核加密 API 未使用。
struct crypto_skcipher *crypto_alloc_skcipher(const char *alg_name, u32 type, u32 mask)
allocate symmetric key cipher handle
Parameters
const char *alg_name
is the cra_name / name or cra_driver_name / driver name of the skcipher cipher
u32 type
specifies the type of the cipher
u32 mask
specifies the mask for the cipher
Description
Allocate a cipher handle for an skcipher. The returned struct crypto_skcipher is the cipher handle that is required for any subsequent API invocation for that skcipher.
Return
allocated cipher handle in case of success; IS_ERR() is true in case
of an error, PTR_ERR() returns the error code.
void crypto_free_skcipher(struct crypto_skcipher *tfm)
zeroize and free cipher handle
Parameters
struct crypto_skcipher *tfm
cipher handle to be freed
Description
If tfm is a NULL or error pointer, this function does nothing.
int crypto_has_skcipher(const char *alg_name, u32 type, u32 mask)
Search for the availability of an skcipher.
Parameters
const char *alg_name
is the cra_name / name or cra_driver_name / driver name of the skcipher
u32 type
specifies the type of the skcipher
u32 mask
specifies the mask for the skcipher
Return
true when the skcipher is known to the kernel crypto API; false otherwise
unsigned int crypto_skcipher_ivsize(struct crypto_skcipher *tfm)
obtain IV size
Parameters
struct crypto_skcipher *tfm
cipher handle
Description
The size of the IV for the skcipher referenced by the cipher handle is returned. This IV size may be zero if the cipher does not need an IV.
Return
IV size in bytes
unsigned int crypto_skcipher_blocksize(struct crypto_skcipher *tfm)
obtain block size of cipher
Parameters
struct crypto_skcipher *tfm
cipher handle
Description
The block size for the skcipher referenced with the cipher handle is returned. The caller may use that information to allocate appropriate memory for the data returned by the encryption or decryption operation
Return
block size of cipher
int crypto_skcipher_setkey(struct crypto_skcipher *tfm, const u8 *key, unsigned int keylen)
set key for cipher
Parameters
struct crypto_skcipher *tfm
cipher handle
const u8 *key
buffer holding the key
unsigned int keylen
length of the key in bytes
Description
The caller provided key is set for the skcipher referenced by the cipher handle.
Note, the key length determines the cipher type. Many block ciphers implement different cipher modes depending on the key size, such as AES-128 vs AES-192 vs. AES-256. When providing a 16 byte key for an AES cipher handle, AES-128 is performed.
Return
0 if the setting of the key was successful; < 0 if an error occurred
struct crypto_skcipher *crypto_skcipher_reqtfm(struct skcipher_request *req)
obtain cipher handle from request
Parameters
struct skcipher_request *req
skcipher_request out of which the cipher handle is to be obtained
Description
Return the crypto_skcipher handle when furnishing an skcipher_request data structure.
Return
crypto_skcipher handle
int crypto_skcipher_encrypt(struct skcipher_request *req)
encrypt plaintext
Parameters
struct skcipher_request *req
reference to the skcipher_request handle that holds all information needed to perform the cipher operation
Description
Encrypt plaintext data using the skcipher_request handle. That data structure and how it is filled with data is discussed with the skcipher_request_* functions.
Return
0 if the cipher operation was successful; < 0 if an error occurred
int crypto_skcipher_decrypt(struct skcipher_request *req)
decrypt ciphertext
Parameters
struct skcipher_request *req
reference to the skcipher_request handle that holds all information needed to perform the cipher operation
Description
Decrypt ciphertext data using the skcipher_request handle. That data structure and how it is filled with data is discussed with the skcipher_request_* functions.
Return
0 if the cipher operation was successful; < 0 if an error occurred
对称密钥密码请求句柄
skcipher_request数据结构包含指向对称密钥密码操作所需数据的所有指针。这包括密码句柄(可由多个skcipher_request实例使用)、指向明文和密文的指针、异步回调函数等。它充当 skcipher_request_* API 调用的句柄,其方式类似于 crypto_skcipher_* API 调用的 skcipher 句柄。
unsigned int crypto_skcipher_reqsize(struct crypto_skcipher *tfm)
obtain size of the request data structure
Parameters
struct crypto_skcipher *tfm
cipher handle
Return
number of bytes
void skcipher_request_set_tfm(struct skcipher_request *req, struct crypto_skcipher *tfm)
update cipher handle reference in request
Parameters
struct skcipher_request *req
request handle to be modified
struct crypto_skcipher *tfm
cipher handle that shall be added to the request handle
Description
Allow the caller to replace the existing skcipher handle in the request data structure with a different one.
struct skcipher_request *skcipher_request_alloc(struct crypto_skcipher *tfm, gfp_t gfp)
allocate request data structure
Parameters
struct crypto_skcipher *tfm
cipher handle to be registered with the request
gfp_t gfp
memory allocation flag that is handed to kmalloc by the API call.
Description
Allocate the request data structure that must be used with the skcipher encrypt and decrypt API calls. During the allocation, the provided skcipher handle is registered in the request data structure.
Return
allocated request handle in case of success, or NULL if out of memory
void skcipher_request_free(struct skcipher_request *req)
zeroize and free request data structure
Parameters
struct skcipher_request *req
request data structure cipher handle to be freed
void skcipher_request_set_callback(struct skcipher_request *req, u32 flags, crypto_completion_t compl, void *data)
set asynchronous callback function
Parameters
struct skcipher_request *req
request handle
u32 flags
specify zero or an ORing of the flags CRYPTO_TFM_REQ_MAY_BACKLOG the request queue may back log and increase the wait queue beyond the initial maximum size; CRYPTO_TFM_REQ_MAY_SLEEP the request processing may sleep
crypto_completion_t compl
callback function pointer to be registered with the request handle
void *data
The data pointer refers to memory that is not used by the kernel crypto API, but provided to the callback function for it to use. Here, the caller can provide a reference to memory the callback function can operate on. As the callback function is invoked asynchronously to the related functionality, it may need to access data structures of the related functionality which can be referenced using this pointer. The callback function can access the memory via the "data" field in the crypto_async_request data structure provided to the callback function.
Description
This function allows setting the callback function that is triggered once the cipher operation completes.
The callback function is registered with the skcipher_request handle and must comply with the following template:
void callback_function(struct crypto_async_request *req, int error)
void skcipher_request_set_crypt(struct skcipher_request *req, struct scatterlist *src, struct scatterlist *dst, unsigned int cryptlen, void *iv)
set data buffers
Parameters
struct skcipher_request *req
request handle
struct scatterlist *src
source scatter / gather list
struct scatterlist *dst
destination scatter / gather list
unsigned int cryptlen
number of bytes to process from src
void *iv
IV for the cipher operation which must comply with the IV size defined by crypto_skcipher_ivsize
Description
This function allows setting of the source data and destination data scatter / gather lists.
For encryption, the source is treated as the plaintext and the destination is the ciphertext. For a decryption operation, the use is reversed - the source is the ciphertext and the destination is the plaintext.
单块密码 API
单块密码 API 用于处理类型为 CRYPTO_ALG_TYPE_CIPHER(在 /proc/crypto 中列为 “cipher” 类型)的密码算法。
通过使用单块密码 API 调用,可以实现基本密码原语的操作。这些密码原语不包括任何块链操作,包括 IV 处理。
这个单块密码 API 的目的是为了支持模板或其他仅需要逐个块执行密码操作的概念的实现。模板会以块为单位调用底层密码原语,并处理这些密码操作的输入或输出数据之一。
struct crypto_cipher *crypto_alloc_cipher(const char *alg_name, u32 type, u32 mask)
allocate single block cipher handle
Parameters
const char *alg_name
is the cra_name / name or cra_driver_name / driver name of the single block cipher
u32 type
specifies the type of the cipher
u32 mask
specifies the mask for the cipher
Description
Allocate a cipher handle for a single block cipher. The returned struct crypto_cipher is the cipher handle that is required for any subsequent API invocation for that single block cipher.
Return
allocated cipher handle in case of success; IS_ERR() is true in case
of an error, PTR_ERR() returns the error code.
void crypto_free_cipher(struct crypto_cipher *tfm)
zeroize and free the single block cipher handle
Parameters
struct crypto_cipher *tfm
cipher handle to be freed
int crypto_has_cipher(const char *alg_name, u32 type, u32 mask)
Search for the availability of a single block cipher
Parameters
const char *alg_name
is the cra_name / name or cra_driver_name / driver name of the single block cipher
u32 type
specifies the type of the cipher
u32 mask
specifies the mask for the cipher
Return
true when the single block cipher is known to the kernel crypto API;
false otherwise
unsigned int crypto_cipher_blocksize(struct crypto_cipher *tfm)
obtain block size for cipher
Parameters
struct crypto_cipher *tfm
cipher handle
Description
The block size for the single block cipher referenced with the cipher handle tfm is returned. The caller may use that information to allocate appropriate memory for the data returned by the encryption or decryption operation
Return
block size of cipher
int crypto_cipher_setkey(struct crypto_cipher *tfm, const u8 *key, unsigned int keylen)
set key for cipher
Parameters
struct crypto_cipher *tfm
cipher handle
const u8 *key
buffer holding the key
unsigned int keylen
length of the key in bytes
Description
The caller provided key is set for the single block cipher referenced by the cipher handle.
Note, the key length determines the cipher type. Many block ciphers implement different cipher modes depending on the key size, such as AES-128 vs AES-192 vs. AES-256. When providing a 16 byte key for an AES cipher handle, AES-128 is performed.
Return
0 if the setting of the key was successful; < 0 if an error occurred
void crypto_cipher_encrypt_one(struct crypto_cipher *tfm, u8 *dst, const u8 *src)
encrypt one block of plaintext
Parameters
struct crypto_cipher *tfm
cipher handle
u8 *dst
points to the buffer that will be filled with the ciphertext
const u8 *src
buffer holding the plaintext to be encrypted
Description
Invoke the encryption operation of one block. The caller must ensure that the plaintext and ciphertext buffers are at least one block in size.
void crypto_cipher_decrypt_one(struct crypto_cipher *tfm, u8 *dst, const u8 *src)
decrypt one block of ciphertext
Parameters
struct crypto_cipher *tfm
cipher handle
u8 *dst
points to the buffer that will be filled with the plaintext
const u8 *src
buffer holding the ciphertext to be decrypted
Description
Invoke the decryption operation of one block. The caller must ensure that the plaintext and ciphertext buffers are at least one block in size.
ref: https://www.kernel.org/doc/html/latest/crypto/api-skcipher.html