linux4.14 加密框架 —— 算法上下文(1)——tfm简介

目录

1. struct crypto_tfm

2. tfm的分配


      有了算法实例,仅表示内核拥有这一种“算法”——加引号的意思是说,它可能并不以
类似 md5.c这样的源代码形式存现,而是通过模版动态创建的。实际要使用该算法,需要为算法分配“运行的对像”,即 tfm。

/*
 * Transforms: user-instantiated objects which encapsulate algorithms
 * and core processing logic.  Managed via crypto_alloc_*() and
 * crypto_free_*(), as well as the various helpers below.
 */

1. struct crypto_tfm

      内核加密框架中,使用结构 crypto_alg 来描述一个算法,每一个算法(实例)相当于一个
类,在实际的使用环境中,需要为它分配一个对像,在内核加密框架中,这个“对像”被称 为transform(简称 tfm)。transform意味“变换”,可能译为“蜕变”更为合适。

      tfm是加密框架中一个极为重要的概念,它由结构crypto_tfm描述

#define crt_ablkcipher	crt_u.ablkcipher
#define crt_blkcipher	crt_u.blkcipher
#define crt_cipher	crt_u.cipher
#define crt_compress	crt_u.compress
struct crypto_tfm {

	u32 crt_flags;
	
	union {
		struct ablkcipher_tfm ablkcipher;
		struct blkcipher_tfm blkcipher;
		struct cipher_tfm cipher;
		struct compress_tfm compress;
	} crt_u;

	void (*exit)(struct crypto_tfm *tfm);
	
	struct crypto_alg *__crt_alg;

	void *__crt_ctx[] CRYPTO_MINALIGN_ATTR;
};

      这些成员的作用,将在后面一一看到,值得注意的是,针对每种算法不同,结构定义了一个名为 crt_u 的联合体,以对应每种算法的 tfm 的具体操作,例如加密/解密,求hash,压缩/解压等,加密框架引入了一组名为xxx_tfm的结构封装,xxx表示算法类型,也就是crt_u成 员。其定义如下:

struct ablkcipher_tfm {
	int (*setkey)(struct crypto_ablkcipher *tfm, const u8 *key,
	              unsigned int keylen);
	int (*encrypt)(struct ablkcipher_request *req);
	int (*decrypt)(struct ablkcipher_request *req);

	struct crypto_ablkcipher *base;

	unsigned int ivsize;
	unsigned int reqsize;
};

struct blkcipher_tfm {
	void *iv;
	int (*setkey)(struct crypto_tfm *tfm, const u8 *key,
		      unsigned int keylen);
	int (*encrypt)(struct blkcipher_desc *desc, struct scatterlist *dst,
		       struct scatterlist *src, unsigned int nbytes);
	int (*decrypt)(struct blkcipher_desc *desc, struct scatterlist *dst,
		       struct scatterlist *src, unsigned int nbytes);
};

struct cipher_tfm {
	int (*cit_setkey)(struct crypto_tfm *tfm,
	                  const u8 *key, unsigned int keylen);
	void (*cit_encrypt_one)(struct crypto_tfm *tfm, u8 *dst, const u8 *src);
	void (*cit_decrypt_one)(struct crypto_tfm *tfm, u8 *dst, const u8 *src);
};

struct compress_tfm {
	int (*cot_compress)(struct crypto_tfm *tfm,
	                    const u8 *src, unsigned int slen,
	                    u8 *dst, unsigned int *dlen);
	int (*cot_decompress)(struct crypto_tfm *tfm,
	                      const u8 *src, unsigned int slen,
	                      u8 *dst, unsigned int *dlen);
};

struct crypto_ablkcipher {
	struct crypto_tfm base;
};

struct crypto_blkcipher {
	struct crypto_tfm base;
};

struct crypto_cipher {
	struct crypto_tfm base;
};

struct crypto_comp {
	struct crypto_tfm base;
};

      其 base 成员就是相应算法的 tfm。因为它们拥有相应的起始地址,可以很方便地强制类型
转换来操作,内核为此专门定义了一组函数, 以ablkcipher为例,完成这一工作的是:

struct cryptd_ablkcipher {
	struct crypto_ablkcipher base;
};

static inline struct cryptd_ablkcipher *__cryptd_ablkcipher_cast(
	struct crypto_ablkcipher *tfm)
{
	return (struct cryptd_ablkcipher *)tfm;
}

2. tfm的分配

      对于算法的实始化,其核心功能就是分配一个 tfm,并设置其上下文环境,例如密钥等参数,然后初始化上述struct xxx_tfm结构.

static inline struct crypto_cipher *crypto_alloc_cipher(const char *alg_name,
							u32 type, u32 mask);
struct crypto_skcipher *crypto_alloc_skcipher(const char *alg_name,
					      u32 type, u32 mask);
struct crypto_rng *crypto_alloc_rng(const char *alg_name, u32 type, u32 mask);
struct crypto_ahash *crypto_alloc_ahash(const char *alg_name, u32 type,
					u32 mask);
struct crypto_aead *crypto_alloc_aead(const char *alg_name, u32 type, u32 mask);
struct crypto_acomp *crypto_alloc_acomp(const char *alg_name, u32 type,
					u32 mask);
struct crypto_kpp *crypto_alloc_kpp(const char *alg_name, u32 type, u32 mask);

分析它们的调用

crypto_alloc_cipher
	crypto_alloc_base
        crypto_alg_mod_lookup
        __crypto_alloc_tfm
	return __crypto_cipher_cast(crypto_alloc_base(alg_name, type, mask));
crypto_alloc_skcipher
	return crypto_alloc_tfm(alg_name, &crypto_skcipher_type2, type, mask);
crypto_alloc_rng
	return crypto_alloc_tfm(alg_name, &crypto_rng_type, type, mask);
crypto_alloc_ahash
	return crypto_alloc_tfm(alg_name, &crypto_ahash_type, type, mask);
crypto_alloc_aead
	return crypto_alloc_tfm(alg_name, &crypto_aead_type, type, mask);
crypto_alloc_acomp
	return crypto_alloc_tfm(alg_name, &crypto_acomp_type, type, mask);
crypto_alloc_kpp
	return crypto_alloc_tfm(alg_name, &crypto_kpp_type, type, mask);

发现,基本上只有两种分配方式。一个是__crypto_alloc_tfm。另外一个是crypto_alloc_tfm。分别对应crypto_alloc_cipher和其他的算法。后面我们会简单分析一下两种算法,aes和哈希算法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是基于内核模式下AES加密解密算法的C代码实现: ```c #include <linux/crypto.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> #define MSG_LEN 16 static char *key = "01234567890123456789012345678901"; // 32字节的密钥 static char *msg = "Hello, world!"; // 16字节的明文数据 static char encrypted[MSG_LEN]; static char decrypted[MSG_LEN]; static int __init aes_init(void) { struct crypto_cipher *tfm; int i; printk(KERN_INFO "AES module loaded.\n"); tfm = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC); if (IS_ERR(tfm)) { printk(KERN_ERR "Unable to allocate cipher.\n"); return -1; } crypto_cipher_setkey(tfm, key, strlen(key)); crypto_cipher_encrypt_one(tfm, encrypted, msg); printk(KERN_INFO "Encrypted message: "); for (i = 0; i < MSG_LEN; i++) { printk("%02x ", encrypted[i]); } printk("\n"); crypto_cipher_decrypt_one(tfm, decrypted, encrypted); printk(KERN_INFO "Decrypted message: "); for (i = 0; i < MSG_LEN; i++) { printk("%c", decrypted[i]); } printk("\n"); crypto_free_cipher(tfm); return 0; } static void __exit aes_exit(void) { printk(KERN_INFO "AES module unloaded.\n"); } module_init(aes_init); module_exit(aes_exit); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("AES encryption/decryption module"); MODULE_AUTHOR("Your Name"); ``` 在此示例代码中,我们使用了Linux内核中的`crypto`库来进行AES加密解密。首先,我们定义了一个32字节的密钥和一个16字节的明文数据。然后,我们分配了一个AES加密解密算法上下文,设置了密钥并对明文进行加密。接着,我们打印出加密后的数据,并对其进行解密并打印出解密后的结果。最后,我们释放了上下文并完成了模块的加载。 需要注意的是,在内核中进行加密解密操作需要特殊的权限,因此需要使用root权限来加载和卸载此模块。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值