参考链接
- Linux加密框架中的主要数据结构(二)_家有一希的博客-CSDN博客
定义
- 通用算法说明数据结构crypto_alg的联合体成员变量cra_u中包含多种算法的个性化属性,如分组算法、块加密算法、压缩算法、伪随机数算法等,但不包含哈希算法的个性化属性。
- Linux加密框架crypto crypto_alg|cipher_alg数据结构|AES例子_CHYabc123456hh的博客-CSDN博客
- 加密框架以通用算法说明数据结构crypto_alg为基类定义了哈希算法说明数据结构,根据算法实现不同哈希算法说明分为同步哈希(synchronous hash)算法说明数据结构struct shash_alg和异步哈希(asynchronous hash)算法说明数据结构struct ahash_alg。
- 哈希算法 的 结构 需要派生继承自 通用数据结构 crypto_alg
- hash.h - include/crypto/hash.h - Linux source code (v5.15.11) - Bootlin
同步哈希(synchronous hash)算法说明数据结构struct shash_alg
/*** struct shash_alg - synchronous message digest definition* @init: see struct ahash_alg* @update: see struct ahash_alg* @final: see struct ahash_alg* @finup: see struct ahash_alg* @digest: see struct ahash_alg* @export: see struct ahash_alg* @import: see struct ahash_alg* @setkey: see struct ahash_alg* @init_tfm: Initialize the cryptographic transformation object.* This function is called only once at the instantiation* time, right after the transformation context was* allocated. In case the cryptographic hardware has* some special requirements which need to be handled* by software, this function shall check for the precise* requirement of the transformation and put any software* fallbacks in place.* @exit_tfm: Deinitialize the cryptographic transformation object.* This is a counterpart to @init_tfm, used to remove* various changes set in @init_tfm.* @digestsize: see struct ahash_alg* @statesize: see struct ahash_alg* @descsize: Size of the operational state for the message digest. This state* size is the memory size that needs to be allocated for* shash_desc.__ctx* @base: internally used*/
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);int (*init_tfm)(struct crypto_shash *tfm);void (*exit_tfm)(struct crypto_shash *tfm);unsigned int descsize;/* These fields must match hash_alg_common. */unsigned int digestsize__attribute__ ((aligned(__alignof__(struct hash_alg_common))));unsigned int statesize;struct crypto_alg base;
};
异步哈希(asynchronous hash)算法说明数据结构struct ahash_alg
/*** struct ahash_alg - asynchronous message digest definition* @init: **[mandatory]** Initialize the transformation context. Intended only to initialize the* state of the HASH transformation at the beginning. This shall fill in* the internal structures used during the entire duration of the whole* transformation. No data processing happens at this point. Driver code* implementation must not use req->result.* @update: **[mandatory]** Push a chunk of data into the driver for transformation. This* function actually pushes blocks of data from upper layers into the* driver, which then passes those to the hardware as seen fit. This* function must not finalize the HASH transformation by calculating the* final message digest as this only adds more data into the* transformation. This function shall not modify the transformation* context, as this function may be called in parallel with the same* transformation object. Data processing can happen synchronously* [SHASH] or asynchronously [AHASH] at this point. Driver must not use* req->result.* @final: **[mandatory]** Retrieve result from the driver. This function finalizes the* transformation and retrieves the resulting hash from the driver and* pushes it back to upper layers. No data processing happens at this* point unless hardware requires it to finish the transformation* (then the data buffered by the device driver is processed).* @finup: **[optional]** Combination of @update and @final. This function is effectively a* combination of @update and @final calls issued in sequence. As some* hardware cannot do @update and @final separately, this callback was* added to allow such hardware to be used at least by IPsec. Data* processing can happen synchronously [SHASH] or asynchronously [AHASH]* at this point.* @digest: Combination of @init and @update and @final. This function* effectively behaves as the entire chain of operations, @init,* @update and @final issued in sequence. Just like @finup, this was* added for hardware which cannot do even the @finup, but can only do* the whole transformation in one run. Data processing can happen* synchronously [SHASH] or asynchronously [AHASH] at this point.* @setkey: Set optional key used by the hashing algorithm. Intended to push* optional key used by the hashing algorithm from upper layers into* the driver. This function can store the key in the transformation* context or can outright program it into the hardware. In the former* case, one must be careful to program the key into the hardware at* appropriate time and one must be careful that .setkey() can be* called multiple times during the existence of the transformation* object. Not all hashing algorithms do implement this function as it* is only needed for keyed message digests. SHAx/MDx/CRCx do NOT* implement this function. HMAC(MDx)/HMAC(SHAx)/CMAC(AES) do implement* this function. This function must be called before any other of the* @init, @update, @final, @finup, @digest is called. No data* processing happens at this point.* @export: Export partial state of the transformation. This function dumps the* entire state of the ongoing transformation into a provided block of* data so it can be @import 'ed back later on. This is useful in case* you want to save partial result of the transformation after* processing certain amount of data and reload this partial result* multiple times later on for multiple re-use. No data processing* happens at this point. Driver must not use req->result.* @import: Import partial state of the transformation. This function loads the* entire state of the ongoing transformation from a provided block of* data so the transformation can continue from this point onward. No* data processing happens at this point. Driver must not use* req->result.* @init_tfm: Initialize the cryptographic transformation object.* This function is called only once at the instantiation* time, right after the transformation context was* allocated. In case the cryptographic hardware has* some special requirements which need to be handled* by software, this function shall check for the precise* requirement of the transformation and put any software* fallbacks in place.* @exit_tfm: Deinitialize the cryptographic transformation object.* This is a counterpart to @init_tfm, used to remove* various changes set in @init_tfm.* @halg: see struct hash_alg_common*/
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);int (*init_tfm)(struct crypto_ahash *tfm);void (*exit_tfm)(struct crypto_ahash *tfm);struct hash_alg_common halg;
};
算法接口
- init: 三段式调用的初始化接口;
- update:三段式调用的计算更新接口;
- final: 三段式调用的结束(输出)接口;
- finup: 两段式调用的计算更新和结束(输出)接口; 是将final和update合在一起的
- digest: 一段式调用的摘要计算接口;
- export: 上下文环境导出接口;
- import: 上下文环境导入接口;
- setkey: HMAC密钥设置接口。
- init_tfm:初始化加密转换对象
- exit_tfm: 取消初始化加密转换对象
汇总
- 同步哈希算法说明数据结构中的算法接口为哈希算法接口全集,包括最小集的三段式调用接口(init、update和final),也包括在最小集基础上衍生出来的两段式调用接口(init和finup)以及一段式调用接口(digest)。
- 每种哈希算法只需要实现算法接口的最小集(init、update和final)即可,即实现三段式调用接口即可,在注册算法时将使用默认的算法接口作为算法未定义接口的实现。
- 以MD5算法为例,其算法说明只定义了init、update和final三段式调用接口,未定义finup和digest等接口,这样在注册算法时将使用同步哈希算法默认接口shash_finup_unaligned和shash_diget_unaligned作为MD5算法的finup和digest等接口的实现。
- 分析代码,shash_finup_unaligned和shash_diget_unaligned等接口都是在算法已实现的三段式调用接口基础上实现具体功能的。同步哈希算法的上下文运行空间由同步哈希算法描述符desc提供。
- 与静态分组算法和动态分组算法(即块加密算法)对应不同的个性化属性数据结构不同,静态哈希算法和动态哈希算法(即HMAC算法)对应相同的个性化属性数据结构。
- 个性化属性数据结构中的算法接口是静态哈希算法和动态哈希算法的算法接口合集,如静态哈希算法不用实现setkey接口(将默认的shash_no_setkey作为setkey接口实现),而HMAC算法是与密钥相关的,涉及到密钥输入必须实现setkey接口。由于在分时分段计算(如HMAC运算)中,需要更新或切换哈希算法的上下文环境(与具体哈希算法实现相关),因此哈希算法还必须实现import和export两个接口。在加密框架支持的哈希算法中只有MD4算法未import和export两个接口,因此MD4算法无法支持分时分段调用,也无法实现HMAC运算。
- 注:所谓同步指发出一个功能调用时,在没有得到结果之前,该调用不会返回。当一个异步调用发出后,需要其他部件协作或需要等待一段时间,因此调用者不能立刻得到结果,但调用会立刻返回。等处理完成后,由部件通过状态通知和回调来通知调用者。
- 注:加密框架将同步哈希算法说明和异步哈希算法说明的通用部分抽象为数据结构hash_alg_common,如下所示,其成员变量与数据结构struct shash_alg最后三个成员变量相同。 最新版文直接将 这三个成员变量使用封装好的结构体 hash_alg_common 进行替代
同步和异步通用部分抽象 hash_alg_common
- hash.h - include/crypto/hash.h - Linux source code (v5.15.11) - Bootlin
/*** struct hash_alg_common - define properties of message digest* @digestsize: Size of the result of the transformation. A buffer of this size* must be available to the @final and @finup calls, so they can* store the resulting hash into it. For various predefined sizes,* search include/crypto/ using* git grep _DIGEST_SIZE include/crypto.* @statesize: Size of the block for partial state of the transformation. A* buffer of this size must be passed to the @export function as it* will save the partial state of the transformation into it. On the* other side, the @import function will load the state from a* buffer of this size as well.* @base: Start of data structure of cipher algorithm. The common data* structure of crypto_alg contains information common to all ciphers.* The hash_alg_common data structure now adds the hash-specific* information.*/
struct hash_alg_common {unsigned int digestsize;unsigned int statesize;struct crypto_alg base;
};
- hash_alg_common内部包含crypto_alg结构体,这个结构体是通用密码学密文统一的结构体,哈希在其通用的基础之上添加了 哈希独有的地方
- crypto.h - include/linux/crypto.h - Linux source code (v5.15.11) - Bootlin
- 通用结构体定义如下