Linux加密框架crypto AES代码相关

 例子

  • aes_generic.c - crypto/aes_generic.c - Linux source code (v5.15.11) - Bootlin
static struct crypto_alg aes_alg = {.cra_name		=	"aes",.cra_driver_name	=	"aes-generic",.cra_priority		=	100,.cra_flags		=	CRYPTO_ALG_TYPE_CIPHER,.cra_blocksize		=	AES_BLOCK_SIZE,.cra_ctxsize		=	sizeof(struct crypto_aes_ctx),.cra_module		=	THIS_MODULE,.cra_u			=	{.cipher = {.cia_min_keysize	=	AES_MIN_KEY_SIZE,.cia_max_keysize	=	AES_MAX_KEY_SIZE,.cia_setkey		=	crypto_aes_set_key,.cia_encrypt		=	crypto_aes_encrypt,.cia_decrypt		=	crypto_aes_decrypt}}
};
  • 从上述定义可知AES算法的属性信息,如下所示:
    • a)算法名为"aes",算法驱动名为"aes-generic"。
    • b)算法的优先级为100  使用的时候,如未特殊指定,按照优先级高低进行使用
    • c)算法的分组长度为AES_BLOCK_SIZE(16)字节
    • d)算法类型为CRYPTO_ALG_TYPE_CIPHER(即分组算法),其个性化属性数据结构为struct cipher_alg,定义如下所示:

cipher_alg

/*** DOC: Block Cipher Algorithm Definitions** These data structures define modular crypto algorithm implementations,* managed via crypto_register_alg() and crypto_unregister_alg().*//*** struct cipher_alg - single-block symmetric ciphers definition* @cia_min_keysize: Minimum key size supported by the transformation. This is*		     the smallest key length supported by this transformation*		     algorithm. This must be set to one of the pre-defined*		     values as this is not hardware specific. Possible values*		     for this field can be found via git grep "_MIN_KEY_SIZE"*		     include/crypto/* @cia_max_keysize: Maximum key size supported by the transformation. This is*		    the largest key length supported by this transformation*		    algorithm. This must be set to one of the pre-defined values*		    as this is not hardware specific. Possible values for this*		    field can be found via git grep "_MAX_KEY_SIZE"*		    include/crypto/* @cia_setkey: Set key for the transformation. This function is used to either*	        program a supplied key into the hardware or store the key in the*	        transformation context for programming it later. Note that this*	        function does modify the transformation context. This function*	        can be called multiple times during the existence of the*	        transformation object, so one must make sure the key is properly*	        reprogrammed into the hardware. This function is also*	        responsible for checking the key length for validity.* @cia_encrypt: Encrypt a single block. This function is used to encrypt a*		 single block of data, which must be @cra_blocksize big. This*		 always operates on a full @cra_blocksize and it is not possible*		 to encrypt a block of smaller size. The supplied buffers must*		 therefore also be at least of @cra_blocksize size. Both the*		 input and output buffers are always aligned to @cra_alignmask.*		 In case either of the input or output buffer supplied by user*		 of the crypto API is not aligned to @cra_alignmask, the crypto*		 API will re-align the buffers. The re-alignment means that a*		 new buffer will be allocated, the data will be copied into the*		 new buffer, then the processing will happen on the new buffer,*		 then the data will be copied back into the original buffer and*		 finally the new buffer will be freed. In case a software*		 fallback was put in place in the @cra_init call, this function*		 might need to use the fallback if the algorithm doesn't support*		 all of the key sizes. In case the key was stored in*		 transformation context, the key might need to be re-programmed*		 into the hardware in this function. This function shall not*		 modify the transformation context, as this function may be*		 called in parallel with the same transformation object.* @cia_decrypt: Decrypt a single block. This is a reverse counterpart to*		 @cia_encrypt, and the conditions are exactly the same.** All fields are mandatory and must be filled.*/
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);
};

分组算法个性化属性包括2个参数和3个算法 接口,如上所示:

2个参数

  • 分组算法输入密钥长度的下限cia_min_keysize和上限cia_max_keysize
  • AES算法密钥长度的下限和上限分别为AES_MIN_KEY_SIZE(16)、AES_MAX_KEY_SIZE(32),但实际上AES算法只支持16B(128bit)、24B(192bit)和32B(256bit)三种密钥长度,如果输入密钥的长度为其他值,在进行密钥扩展(crypto_aes_expand_key)时将返回参数错误,如下所示:

三个算法接口 

  •  分组算法的算法接口,包括密钥设置接口cia_setkey、加密接口cia_encrypt和解密接口cia_decrypt,算法运行的上下文空间由算法实例tfm提供。
  • AES算法的三个算法接口分别为crypto_aes_set_key、aes_encrypt和aes_decrypt。从AES算法加密接口和解密接口的实现流程来看,每次处理一个分组(16B)的数据。
  • AES算法运行的上下文空间是数据结构struct crypto_aes_ctx的一个实例,该数据结构定义(root/include/crypto/aes.h)如下所示:
  • aes.h - include/crypto/aes.h - Linux source code (v5.15.11) - Bootlin

crypto_aes_ctx

/** Please ensure that the first two fields are 16-byte aligned* relative to the start of the structure, i.e., don't move them!*/
struct crypto_aes_ctx {u32 key_enc[AES_MAX_KEYLENGTH_U32];u32 key_dec[AES_MAX_KEYLENGTH_U32];u32 key_length;
};
  • AES算法上下文数据结构包括密钥扩展后的加密密钥key_enc和解密密钥key_dec以及输入的密钥长度key_length。
  • 注:由于算法应用不会直接使用AES算法的算法接口,因此其算法说明aes_alg未设置算法类型常量cra_type。 

crypto_aes_set_key 

aes_expandkey

  • aes.c - lib/crypto/aes.c - Linux source code (v5.15.11) - Bootlin
/*** aes_expandkey - Expands the AES key as described in FIPS-197* @ctx:	The location where the computed key will be stored.* @in_key:	The supplied key.* @key_len:	The length of the supplied key.** Returns 0 on success. The function fails only if an invalid key size (or* pointer) is supplied.* The expanded key size is 240 bytes (max of 14 rounds with a unique 16 bytes* key schedule plus a 16 bytes key which is used before the first round).* The decryption key is prepared for the "Equivalent Inverse Cipher" as* described in FIPS-197. The first slot (16 bytes) of each key (enc or dec) is* for the initial combination, the second slot for the first round and so on.*/
int aes_expandkey(struct crypto_aes_ctx *ctx, const u8 *in_key,unsigned int key_len)
{u32 kwords = key_len / sizeof(u32);u32 rc, i, j;int err;err = aes_check_keylen(key_len);if (err)return err;ctx->key_length = key_len;for (i = 0; i < kwords; i++)ctx->key_enc[i] = get_unaligned_le32(in_key + i * sizeof(u32));for (i = 0, rc = 1; i < 10; i++, rc = mul_by_x(rc)) {u32 *rki = ctx->key_enc + (i * kwords);u32 *rko = rki + kwords;rko[0] = ror32(subw(rki[kwords - 1]), 8) ^ rc ^ rki[0];rko[1] = rko[0] ^ rki[1];rko[2] = rko[1] ^ rki[2];rko[3] = rko[2] ^ rki[3];if (key_len == AES_KEYSIZE_192) {if (i >= 7)break;rko[4] = rko[3] ^ rki[4];rko[5] = rko[4] ^ rki[5];} else if (key_len == AES_KEYSIZE_256) {if (i >= 6)break;rko[4] = subw(rko[3]) ^ rki[4];rko[5] = rko[4] ^ rki[5];rko[6] = rko[5] ^ rki[6];rko[7] = rko[6] ^ rki[7];}}/** Generate the decryption keys for the Equivalent Inverse Cipher.* This involves reversing the order of the round keys, and applying* the Inverse Mix Columns transformation to all but the first and* the last one.*/ctx->key_dec[0] = ctx->key_enc[key_len + 24];ctx->key_dec[1] = ctx->key_enc[key_len + 25];ctx->key_dec[2] = ctx->key_enc[key_len + 26];ctx->key_dec[3] = ctx->key_enc[key_len + 27];for (i = 4, j = key_len + 20; j > 0; i += 4, j -= 4) {ctx->key_dec[i]     = inv_mix_columns(ctx->key_enc[j]);ctx->key_dec[i + 1] = inv_mix_columns(ctx->key_enc[j + 1]);ctx->key_dec[i + 2] = inv_mix_columns(ctx->key_enc[j + 2]);ctx->key_dec[i + 3] = inv_mix_columns(ctx->key_enc[j + 3]);}ctx->key_dec[i]     = ctx->key_enc[0];ctx->key_dec[i + 1] = ctx->key_enc[1];ctx->key_dec[i + 2] = ctx->key_enc[2];ctx->key_dec[i + 3] = ctx->key_enc[3];return 0;
}
EXPORT_SYMBOL(aes_expandkey);

aes_encrypt 

  • aes.c - lib/crypto/aes.c - Linux source code (v5.15.11) - Bootlin
/*** aes_encrypt - Encrypt a single AES block* @ctx:	Context struct containing the key schedule* @out:	Buffer to store the ciphertext* @in:		Buffer containing the plaintext*/
void aes_encrypt(const struct crypto_aes_ctx *ctx, u8 *out, const u8 *in)
{const u32 *rkp = ctx->key_enc + 4;int rounds = 6 + ctx->key_length / 4;u32 st0[4], st1[4];int round;st0[0] = ctx->key_enc[0] ^ get_unaligned_le32(in);st0[1] = ctx->key_enc[1] ^ get_unaligned_le32(in + 4);st0[2] = ctx->key_enc[2] ^ get_unaligned_le32(in + 8);st0[3] = ctx->key_enc[3] ^ get_unaligned_le32(in + 12);/** Force the compiler to emit data independent Sbox references,* by xoring the input with Sbox values that are known to add up* to zero. This pulls the entire Sbox into the D-cache before any* data dependent lookups are done.*/st0[0] ^= aes_sbox[ 0] ^ aes_sbox[ 64] ^ aes_sbox[134] ^ aes_sbox[195];st0[1] ^= aes_sbox[16] ^ aes_sbox[ 82] ^ aes_sbox[158] ^ aes_sbox[221];st0[2] ^= aes_sbox[32] ^ aes_sbox[ 96] ^ aes_sbox[160] ^ aes_sbox[234];st0[3] ^= aes_sbox[48] ^ aes_sbox[112] ^ aes_sbox[186] ^ aes_sbox[241];for (round = 0;; round += 2, rkp += 8) {st1[0] = mix_columns(subshift(st0, 0)) ^ rkp[0];st1[1] = mix_columns(subshift(st0, 1)) ^ rkp[1];st1[2] = mix_columns(subshift(st0, 2)) ^ rkp[2];st1[3] = mix_columns(subshift(st0, 3)) ^ rkp[3];if (round == rounds - 2)break;st0[0] = mix_columns(subshift(st1, 0)) ^ rkp[4];st0[1] = mix_columns(subshift(st1, 1)) ^ rkp[5];st0[2] = mix_columns(subshift(st1, 2)) ^ rkp[6];st0[3] = mix_columns(subshift(st1, 3)) ^ rkp[7];}put_unaligned_le32(subshift(st1, 0) ^ rkp[4], out);put_unaligned_le32(subshift(st1, 1) ^ rkp[5], out + 4);put_unaligned_le32(subshift(st1, 2) ^ rkp[6], out + 8);put_unaligned_le32(subshift(st1, 3) ^ rkp[7], out + 12);
}
EXPORT_SYMBOL(aes_encrypt);

aes_decrypt 

  • aes.c - lib/crypto/aes.c - Linux source code (v5.15.11) - Bootlin
/*** aes_decrypt - Decrypt a single AES block* @ctx:	Context struct containing the key schedule* @out:	Buffer to store the plaintext* @in:		Buffer containing the ciphertext*/
void aes_decrypt(const struct crypto_aes_ctx *ctx, u8 *out, const u8 *in)
{const u32 *rkp = ctx->key_dec + 4;int rounds = 6 + ctx->key_length / 4;u32 st0[4], st1[4];int round;st0[0] = ctx->key_dec[0] ^ get_unaligned_le32(in);st0[1] = ctx->key_dec[1] ^ get_unaligned_le32(in + 4);st0[2] = ctx->key_dec[2] ^ get_unaligned_le32(in + 8);st0[3] = ctx->key_dec[3] ^ get_unaligned_le32(in + 12);/** Force the compiler to emit data independent Sbox references,* by xoring the input with Sbox values that are known to add up* to zero. This pulls the entire Sbox into the D-cache before any* data dependent lookups are done.*/st0[0] ^= aes_inv_sbox[ 0] ^ aes_inv_sbox[ 64] ^ aes_inv_sbox[129] ^ aes_inv_sbox[200];st0[1] ^= aes_inv_sbox[16] ^ aes_inv_sbox[ 83] ^ aes_inv_sbox[150] ^ aes_inv_sbox[212];st0[2] ^= aes_inv_sbox[32] ^ aes_inv_sbox[ 96] ^ aes_inv_sbox[160] ^ aes_inv_sbox[236];st0[3] ^= aes_inv_sbox[48] ^ aes_inv_sbox[112] ^ aes_inv_sbox[187] ^ aes_inv_sbox[247];for (round = 0;; round += 2, rkp += 8) {st1[0] = inv_mix_columns(inv_subshift(st0, 0)) ^ rkp[0];st1[1] = inv_mix_columns(inv_subshift(st0, 1)) ^ rkp[1];st1[2] = inv_mix_columns(inv_subshift(st0, 2)) ^ rkp[2];st1[3] = inv_mix_columns(inv_subshift(st0, 3)) ^ rkp[3];if (round == rounds - 2)break;st0[0] = inv_mix_columns(inv_subshift(st1, 0)) ^ rkp[4];st0[1] = inv_mix_columns(inv_subshift(st1, 1)) ^ rkp[5];st0[2] = inv_mix_columns(inv_subshift(st1, 2)) ^ rkp[6];st0[3] = inv_mix_columns(inv_subshift(st1, 3)) ^ rkp[7];}put_unaligned_le32(inv_subshift(st1, 0) ^ rkp[4], out);put_unaligned_le32(inv_subshift(st1, 1) ^ rkp[5], out + 4);put_unaligned_le32(inv_subshift(st1, 2) ^ rkp[6], out + 8);put_unaligned_le32(inv_subshift(st1, 3) ^ rkp[7], out + 12);
}
EXPORT_SYMBOL(aes_decrypt);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/446106.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux加密框架 crypto RC4

参考链接 arc4.h Linux加密框架中的主要数据结构&#xff08;一&#xff09;_家有一希的博客-CSDN博客 头文件 arc4.h - include/crypto/arc4.h - Linux source code (v5.15.11) - Bootlin实现代码 arc4.c arc4.c - crypto/arc4.c - Linux source code (v5.15.11) - Bootlin…

Linux加密框架 crypto 哈希算法说明 同步哈希shash_alg | 异步哈希 ahash_alg | 通用部分抽象 hash_alg_common

参考链接 Linux加密框架中的主要数据结构&#xff08;二&#xff09;_家有一希的博客-CSDN博客 定义 通用算法说明数据结构crypto_alg的联合体成员变量cra_u中包含多种算法的个性化属性&#xff0c;如分组算法、块加密算法、压缩算法、伪随机数算法等&#xff0c;但不包含哈希…

Linux加密框架 crypto 哈希算法举例 MD5

参考链接 Linux加密框架 crypto 哈希算法说明 同步哈希shash_alg | 异步哈希 ahash_alg | 通用部分抽象 hash_alg_common_CHYabc123456hh的博客-CSDN博客Linux加密框架中的主要数据结构&#xff08;二&#xff09;_家有一希的博客-CSDN博客 MD5 md5.h - include/crypto/md5.h …

事务没提交的数据查的出来吗?_“金三银四”面试官:说说事务的ACID,什么是脏读、幻读?...

一、事务事务是数据库管理系统执行过程中的一个逻辑单位&#xff0c;由一个有限的数据库操作序列构成。--摘自百科在MySQL里&#xff0c;事务是在引擎层面实现&#xff0c;比如MyIsam不支持&#xff0c;InnoDB支持面试清单&#xff08;Java岗&#xff09;&#xff1a;JavaJVM数…

Linux加密框架 crypto 算法模板

参考链接 Linux加密框架中的主要数据结构&#xff08;三&#xff09;_家有一希的博客-CSDN博客algapi.h - include/crypto/algapi.h - Linux source code (v5.15.11) - Bootlin 定义 struct crypto_template {struct list_head list;struct hlist_head instances;struct modu…

Linux加密框架 crypto 算法模板 CBC模板举例

参考链接 Linux加密框架中的主要数据结构&#xff08;三&#xff09;_家有一希的博客-CSDN博客https://blog.csdn.net/CHYabc123456hh/article/details/122194754 CBC算法模板 cbc.c - crypto/cbc.c - Linux source code (v5.15.11) - BootlinCBC算法模板属性 1)CBC算法模板名…

leetcode数组汇总_LeetCode刷题实战43:字符串相乘

算法的重要性&#xff0c;我就不多说了吧&#xff0c;想去大厂&#xff0c;就必须要经过基础知识和业务逻辑面试算法面试。所以&#xff0c;为了提高大家的算法能力&#xff0c;这个公众号后续每天带大家做一道算法题&#xff0c;题目就从LeetCode上面选 &#xff01;今天和大家…

Linux加密框架 crypto 算法模板 HMAC模板举例

参考链接 Linux加密框架中的主要数据结构&#xff08;三&#xff09;_家有一希的博客-CSDN博客Linux加密框架 crypto 算法模板_CHYabc123456hh的博客-CSDN博客 HMAC算法模板 hmac.c - crypto/hmac.c - Linux source code (v5.15.11) - Bootlinhmac.c - crypto/hmac.c - Linux…

判断非负整数是否是3的倍数_五年级数学因数与倍数知识点汇总与解题方法技巧...

在日常教学过程中&#xff0c;我发现孩子们和某些家长对学习数学的方法有一些误区&#xff0c;就是觉着数学&#xff0c;单纯就是逻辑思维&#xff0c;只要多做练习题就能学好&#xff0c;但是不是这样的&#xff0c;低年级的学生&#xff0c;学习数学还是以背诵为主&#xff0…

tcp通讯一次最多能发送多少数据?_关于TCP/IP,必须知道的十个知识点

本文整理了一些TCP/IP协议簇中需要必知必会的十大问题&#xff0c;既是面试高频问题&#xff0c;又是程序员必备基础素养。一、TCP/IP模型TCP/IP协议模型&#xff08;Transmission Control Protocol/Internet Protocol&#xff09;&#xff0c;包含了一系列构成互联网基础的网络…

Linux内核crypto子系统的调用逻辑

testmgr.c - crypto/testmgr.c - Linux source code (v5.15.11) - Bootlin上述代码是内核内部即crypto子系统对外提供密码服务的测试程序调用流程&#xff1a;crypto API <—> crypto core <—> crypto_register_alg处于用户态的程序想要调用处于内核态的密码算法&…

Linux加密框架 crypto算法模板 以及CBC算法模板实例

参考链接 Linux加密框架中的主要数据结构&#xff08;四&#xff09;_家有一希的博客-CSDN博客algapi.h - include/crypto/algapi.h - Linux source code (v5.15.11) - Bootlin struct crypto_instance {struct crypto_alg alg;struct crypto_template *tmpl;union {/* Node i…

tomcat temp 大量 upload 文件_渗透测试之文件上传漏洞总结

文末下载上传环境源码客户端js检查一般都是在网页上写一段javascript脚本&#xff0c;校验上传文件的后缀名&#xff0c;有白名单形式也有黑名单形式。查看源代码可以看到有如下代码对上传文件类型进行了限制&#xff1a;我们可以看到对上传文件类型进行了限制。绕过方法1.我们…

Linux加密框架 crypto算法模板 以及HMAC算法模板实例

HMAC算法模板实例 HMAC算法模板的创建实例的接口是hmac_create函数hmac.c - crypto/hmac.c - Linux source code (v5.15.11) - Bootlin hmac_create输入的参数包括 算法模板 tmpl 和 算法模板实例参数 tbhmac_cretae函数返回的结果为0表示算法模板实例已经创建注册算法模…

linux加密框架 crypto 算法crypto_register_alg的注册流程

算法注册流程 静态算法模块初始化 分组算法模块初始化 AES算法模块&#xff08;aes_generic.c&#xff09;的初始化接口aes_init实现向加密框架注册AES算法的功能&#xff0c;如下所示。aes_generic.c - crypto/aes_generic.c - Linux source code (v5.15.12) - Bootlin sta…

linux加密框架 crypto 静态哈希算法crypto_register_shash注册流程

参考链接 Linux加密框架的算法管理&#xff08;一&#xff09;_家有一希的博客-CSDN博客_linux加密框架设计与实现shash.c - crypto/shash.c - Linux source code (v5.15.12) - Bootlin 函数介绍 crypto_register_shash函数实现向加密框架注册静态哈希算法的功能&#xff0c;…

多个线程访问统一对象的不同方法_C#多线程读写同一文件处理

在多线程访问读写同一个文件时&#xff0c;经常遇到异常&#xff1a;“文件正在由另一进程使用&#xff0c;因此该进程无法访问此文件”。多线程访问统一资源的异常&#xff0c;解决方案1&#xff0c;保证读写操作单线程执行&#xff0c;可以使用lock解决方案2&#xff0c;使用…

linux加密框架 crypto 通用算法注册接口__crypto_register_alg注册流程

函数介绍 __crypto_register_alg函数实现向加密框架注册算法&#xff08;包括静态算法和动态算法&#xff09;的功能&#xff0c;输入参数为算法说明alg&#xff0c;注册成功时返回算法注册用的算法幼虫larval&#xff0c;注册失败时返回失败原因。__crypto_register_alg函数执…

spark官方文档_Spark整合Ray思路漫谈

什么是Ray之前花了大概两到三天把Ray相关的论文&#xff0c;官网文档看了一遍&#xff0c;同时特意去找了一些中文资料看Ray当前在国内的发展情况(以及目前国内大部分人对Ray的认知程度)。先来简单介绍下我对Ray的认知。首先基因很重要&#xff0c;所以我们先需要探查下Ray最初…

linux加密框架 crypto 算法管理 - 算法查找接口 crypto_find_alg

算法查找接口crypto_find_alg 算法实例tfm是算法的一个可运行的副本&#xff0c;因此在创建算法实例前首先要查找确认算法是否已经注册有效&#xff0c;此时算法查找由函数crypto_find_alg实现。补充&#xff1a; struct crypto_tfm *tfm; crypto_tfm类型指针tfm可以理解为指代…