目录
有了算法实例,仅表示内核拥有这一种“算法”——加引号的意思是说,它可能并不以
类似 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和哈希算法。