2021SC@SUDSC
前面的学习了Device Mapper的机制,现在再看dm-crypt就相对容易一点了,因为dm-crypt是基于dm框架的,刚开始在看的时候只知道这么干,但不知道为什么这么干,背后原理性的东西不太清楚。现在再来学习就相对简单了。
在Linux内核中,与密码相关的头文件在/include/crypto/下,其实现是在/crypto/下。与之相关的概念大致有加密、哈希、分组加密模式、块加密、异步块加密等等。因为涉及到密码与加密,所以就先学习了一些与密码相关的知识。
事实上,加密方式应该分为两种,流加密和块加密。大家常用的MD5就是流加密方式,而像那些对称加密(ECB/CBC/CFB/OFB/CTR)、非对称加密(RSA、ECC)都属于组加密。
一、AES
因为下面要介绍AES加密的相关代码,这就需要先了解一下AES加密的相关知识。
AES是典型的对称加密,所谓对称加密就是加解密的密钥相同。在对称加密的的算法中,数据发信方将明文(原始数据)和加密密钥(密钥)一起经过特殊加密算法处理后,使其变成复杂的加密密文发送出去。收信方收到密文后,若想解读原文,则需要使用加密用过的密钥及相同算法的逆算法对密文进行解密,才能使其恢复成可读明文。
AES主要有五种工作模式,即是上面提到的ECB/CBC/CFB/OFB/CTR。
- ECB:电码本模式。直接利用加密算法对数据加密。它一次独立处理一个明文分组,每次使用相同的密钥加密。
- CBC:文分组链接模式。这种模式下加密算法的输入是当前的明文组和上一个密文组的异或,而使用的密钥是相同的。并且,CBC模式如果最后的分组不是完整的分组,则需要填充至b位的满分组。解密时,每个密文分组分别进行解密,再与上一块密文异或就可以恢复成明文。
- CFB:密文反馈模式。一次处理s位,上一块密文作为加密算法的输入,产生的伪随机数输出与明文异或作为下一单元的密文。
- OFB:输出反馈模式。一次处理一个分组,加密算法的输入是上一次加密的输出。
- CTR:计数器模式。每一个明文分组都与一个经过加密的计数器异或。对每个后续的分组,计数器递增。
至于为什么有这么几种方式,虽然相差不大,但是它们都有各自的优缺点以及使用场景。因为这不是我代码分析的最主要部分,而且只需要了解这些知识就可以做下面的代码分析,所以我就没有再接着学习下去。
二、加密算法
既然已经了解了上面那几种加密模式,那么我们就看一下Linux内核代码中的这一块,对于这些加密算法,其都是以内核模块的方式编写的。而对于内核模块的代码,通常的做法就是想看关键的数据结构,再看算法。
crypto_alg的完整定义是在/include/linux/crypto.h中,而且所有的加密、哈希等算法声明都用数据结构都叫做xxx_alg,其实alg就是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;