Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1242678
  • 博文数量: 298
  • 博客积分: 10050
  • 博客等级: 上将
  • 技术积分: 3277
  • 用 户 组: 普通用户
  • 注册时间: 2007-03-14 13:36
文章分类
文章存档

2015年(7)

2012年(1)

2010年(5)

2009年(55)

2008年(73)

2007年(160)

我的朋友

分类: LINUX

2007-07-05 10:50:56

这里是实现一个简单加密文件系统“写操作”的加密过程补充的代码
且只加密sd卡中的文件。

希望在commit_write执行之后就马上强行把这一页的页面数据加密后写到sd上
写完块设备后,将页中的数据再次解密以保证缓存中为明文

总体思想是,在generic_file_write中调用commit_write方法之后,
1. 首先看块设备是否是sd卡,是则加密
2. 加密page中的数据
3. unlock page
4. 调用ll_rw_block写page->buffers队列
5. lock page
6. 将页中的数据再次解密换成明文

注:加密出错机制还暂未考虑

代码如下:
在filemap.c中加入头文件,才能引用宏MAJOR
#include

#define MAX_BUF_PER_PAGE (PAGE_CACHE_SIZE / 512)

下面的代码加到generic_file_write中
status = mapping->a_ops->commit_write(file, page, offset, offset+bytes);之后

unsigned int major;

/*当通过宏MAJOR从b_dev求出bh对应主设备号
*major==60即为sd卡块设备时,进行加密操作
*/
major = MAJOR(page->buffers->b_dev);

if (major == 60) {

struct buffer_head *bh_encrypt, *head, *arr[MAX_BUF_PER_PAGE];

int nr,i;
nr = 0;

——————————————————————————————————
/*
*将page中的BH_Lock已置位选定写入块设备的脏buffers放入arr[]指针数组
*nr记录个数
*/

for(bh_encrypt = head = page->buffers;
bh_encrypt != head; bh_encrypt = bh_encrypt->b_this_page)
{

if(buffer_locked(bh_encrypt))
continue;

arr[nr] = bh_encrypt;

nr++;
}
——————————————————————————————————————
挑选page中的BH_Lock已置位的buffer..简直是大错特错!这个lock置位的问题是bdflush里的write_some_buffers做的。我这里是抢在bdflush之前,应该还是挑选BH_Dirty置位的脏缓冲区,而是由ll_rw_block来将这些bh加锁。
 
/*
*将page中的BH_Dirty已置位选定写入块设备的脏buffers放入arr[]指针数组
*nr记录个数
*/

for(bh_encrypt = head = page->buffers;
bh_encrypt != head; bh_encrypt = bh_encrypt->b_this_page)
{

if(buffer_dirty(bh_encrypt))
continue;

arr[nr] = bh_encrypt;

nr++;
}
 
————————————————
/*
*对于所有需要加密的缓冲区
*/
for(count=0;count{

/*
*首先打印出bh对应的缓冲区数据块区的字符串,利用printk将其保存在一个日志文件中
*(这里bh->b_data应该是值向长度为512的char型的字符串数组指针)
*/
for(i=0;i<512;i++)
{
printk("all the original blocks are %c ",(arr[count]->b_data)[i]);
printk("\n");
}

/*
*将bh对应的缓冲区数据块区的字符与0xff异或
*因为还是实验阶段,这里就没有用加解密算法,利用异或代替比较容易验证
*/
for(i=0;i<512;i++)
(arr[count]->b_data)[i]^ = 0xff;
}

/*
*给page解锁
*利用ll_rw_block将缓冲区立即写入块设备
*给page加锁
*/
UnlockPage(page);

ll_rw_block(WRITE,nr,arr);

LockPage(page);

/*
*对于所有已经加密的缓冲区
*/
for(count=0;count{
/*
*打印出bh对应的已加密的缓冲区数据块区的字符串
*这一步应该可以省略,直接查看文件对比
*/
for(i=0;i<512;i++)
{
printk("all the encrypted blocks are %c ",(arr[count]->b_data)[i]);
printk("\n");
}

/*
*将bh对应已加密的缓冲区数据块区的字符与0xff再次异或
*以保证在缓冲区中的数据为明文
*/
for(i=0;i<512;i++)
(arr[count]->b_data)[i]^ = 0xff;


/*
*打印出bh对应的又再次解密的缓冲区数据块区的字符串
*/
for(i=0;i<512;i++)
{
printk("all the crypted blocks in cache are %c ",(arr[count]->b_data)[i]);
printk("\n");
}

}


} // if (major == 60)
 
不过修改了也重新编译内核有错...
 
塑料袋的说法很值得考虑:
1)ll_rw_block返回后,buffer_head中的内容并没有写到磁盘上。

你的buffer_head都是挂在request中,而request挂在request_queue中,而request挂在tq_disk中。

但是ll_rw_block不会等待启动tq_disk后才返回,更不会等待写完成后才返回,所以返回时,buffer_head的内容还没写到磁盘上,但是你又进行了解密,很可能bottom_half启动tq_disk,tq_disk中真正开始写磁盘时,你已经解密了,真正写的是解密的内容。


2)ll_rw_block中间可能睡眠。在ll_rw_block->submit_bh->__make_request的时候,如果request结构暂时用光了,就会睡眠,等待有request结构被释放。
   
    在这个睡眠的过程中,其他进程换进来。虽然sys_write获得了inode->i_sem信号量,即使没有PG_Lock,其他进程也不能写这个page,但是page有可能是一个影射到其他进程用户空间的page,换进来的其他进程可以在用户空间修改这个page的内容,从而修改了buffer_head中的内容,既你加密的内容。

    等到有了空闲request时,buffer_head中的内容已经被修改了,ll_rw_block在返回前,buffer_head中的加密内容早就改变了。


我想了想,要实现你的目的,可行方法应该是直接修改驱动程序,而不是修改sys_write。
 
也是daemeon说的内存映射问题..
 
反正可能还是要修改驱动或者那个generic_make_request
最初引得那篇论文原文就是:
(1)在generic_make_request()函数中进行加密。Linux操作系统中generic_make_request()函数完成将实际的读写请求传递到下层的设备驱动的任务。

(2)在do_generic_file_read() 中将实际的数据解密


但是读写其实都是利用了submit_bh然后调用了generic_make_request()通过参数传送读写的方法,来实现对设备读写。可是为什么论文里中说"写"是修改generic_make_request(),而"读"是修改do_generic_file_read()呢?不太理解。

还有一个问题,就是在prepare_write中的一个问题。即是页没有缓冲的时候,需要新建一个空白、空闲页面, 为其新新建buffer对列后还会检查其buffer的BH_Uptodate标志,不一致的情况下需要调用ll_rw_block来从磁盘读入块的内容。那么就是写中有读了。这里还需要先把读出来的数据解密。修改一致后再是通过commit_write里面的bdflush进程 调用修改过的generic_make_request进行加密再写磁盘了
 
总之细节问题似乎还需要斟酌...救命!
 

 
阅读(2217) | 评论(7) | 转发(0) |
0

上一篇:红砖绿瓦

下一篇:还是会寂寞

给主人留下些什么吧!~~

chinaunix网友2008-04-13 18:13:02

你好,我最近也在考虑做一个基于TPM的加密文件系统,在linux上开发,单机版的。看了你的blog觉得和我想做的很相似,想向您请教一下,大家多多交流。目前的单机版的加密文件系统做的已经很成熟了,我主要考虑使用TPM带来一些新颖的功能,比如利用PCR将密钥和TPM封装(seal)在一起。 请问您这个加密文件系统也是利用TPM做的吗?能否给些建议!另外,关于文件的一些加密属性比如加密算法、对称密钥长度等您是存在哪里的呢?是存在文件的扩展属性里,还是像ecryptfs一样和文件数据存在一起?盼复!