PadLock AES内核测试模块(二)

PadLock AES内核测试模块(2)


四、源码实现

主要关键的函数说完了,下面结合具体的源码进一步分析:

我通过编译Linux内核模块实现,两个文件:tcrypt.cMakefile。直接通过makemake install就可以实现。

tcrypt.c:
#include <linux/module.h>
#include <linux/crypto.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/scatterlist.h>
#include <linux/slab.h>
#include <linux/highmem.h>

static void my_test_cipher(void) //实现函数
{
	unsigned int ret;
	int i;
	/*必须要用数组,如果用*code这种方式就会输出不正确的数据,还请大神们帮忙解答*/
char code[17] = "1234567887654321";
	char *key = "0123456789abcdef";//关键key
	char *iv = "1234567887654321";//设置iv值
	struct scatterlist sgd;//散集序列,输出
        struct scatterlist sgs;//散集序列,输入
        struct scatterlist sgl;//散集序列,解密后输出
	char last_mem[17];
	char dst_mem[17];
	char *out = NULL;
	char *result = NULL;
	char *src = NULL;
	struct crypto_blkcipher *tfm;
	struct blkcipher_desc desc;
	memset(last_mem,0,17);
	memset(dst_mem,0,17);
/*分配块加密上下文
cbc(aes)表示模式,也可以ofb(aes)等,通常第一个参数为0,第三个参数表示加密模式,
*/
	tfm = crypto_alloc_blkcipher("cbc(aes)", 0, CRYPTO_ALG_ASYNC);	desc.tfm = tfm;
	desc.flags = 0;
/*设置散集序列,将Linux内核中虚拟内存的数据传送到散集序列供dma应用,其中dst_mem,code,last_mem是我们自己设定的值,后面的16表示数据长度大小*/
        sg_init_one(&sgd,dst_mem,16);
        sg_init_one(&sgs,code,16);
        sg_init_one(&sgl,last_mem,16);
	crypto_blkcipher_setkey(tfm,key,16);//设置key
        crypto_blkcipher_set_iv(tfm,iv,16);//设置iv
/*将sgs(散集序列,物理内存)映射到Linux内核的虚拟内存中,目的是我们可以显示其数据*/
	src = kmap(sg_page(&sgs))+sgs.offset;
	printk("the orgin is\n");
	for(i = 0 ;i < sgs.length;i++){
		printk("%c\n",src[i]);
	}
//加密
	ret = crypto_blkcipher_encrypt(&desc,&sgd,&sgs,sgs.length);
	if (!ret) {
		printk("AES encrypt success*************************\n");
		out = kmap(sg_page(&sgd))+sgd.offset;
        	printk("the encrypt  is:\n");
        	for(i = 0;i<sgd.length;i++){
                	printk("%c\n",out[i]);
        	}

	}
	else{
		printk("the encrypt is wrong\n");
		return ;
	}	
       crypto_blkcipher_setkey(tfm,key,16);
       crypto_blkcipher_set_iv(tfm,iv,16);
//解密
       ret = crypto_blkcipher_decrypt(&desc,&sgl,&sgd,sgd.length);
       if(!ret){
                printk(KERN_INFO"hw aes decrypt is success\n"); 
                result = kmap(sg_page(&sgl))+sgl.offset;
                for(i = 0; i < sgl.length;i++){
                        printk("%c\n",result[i]);
		}
        }
	else{
		printk("the decrypt is wrong\n");
		return;
	}
	crypto_free_blkcipher(tfm); 
<span style="white-space:pre">	</span>kunmap(sg_page(&sgs));
<span style="white-space:pre">	</span>kunmap(sg_page(&sgd));
}

static int __init tcrypt_mod_init(void)
{
  	my_test_cipher();
	return 0;
}

/*
 * If an init function is provided, an exit function must also be provided
 * to allow module unload.
 */
static void __exit tcrypt_mod_fini(void) { }

module_init(tcrypt_mod_init);
module_exit(tcrypt_mod_fini);

//MODULE_PARM_DESC(sec, "Length in seconds of speed tests "
//		      "(defaults to zero which uses CPU cycles instead)");

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Quick & dirty crypto testing module");
MODULE_AUTHOR("dachuan");

Makefile:
KONAME = tcrypt.o
IFTEST=$(shell lsmod | grep tcrypt | wc -l)
KERNELDIR := /lib/modules/$(shell uname -r)/build

PWD :=$(shell pwd)
obj-m:=$(KONAME) 

module:
	make -C $(KERNELDIR) M=$(PWD) 

test_install :
ifeq ($(IFTEST),1)
	rmmod tcrypt
	insmod tcrypt.ko
else
	insmod tcrypt.ko
endif
	

install: test_install
.PHONY:install 
	
clean:
	rm *.o *.mod.c  modules.order Module.symvers .*.cmd *.ko
	rm -rf .tmp_versions

五、实验

首先进入带有tcrypt.c makefile的文件夹:

输入命令:

make

PadLock AES内核测试模块(二)

make install

PadLock AES内核测试模块(二)

利用dmesg查看Linux内核信息:

PadLock AES内核测试模块(二)

参考文献

[1]http://blog.****.net/sonicling/article/details/6275898 Linux内核块设备加密分析