了解并学习Linux加密框架设计与实现.doc
《了解并学习Linux加密框架设计与实现.doc》由会员分享,可在线阅读,更多相关《了解并学习Linux加密框架设计与实现.doc(29页珍藏版)》请在三一文库上搜索。
1、了解并学习Linux加密框架设计与实现一、 前言Linux加密框架是内核安全子系统的重要组成部份,同时,它又一个的独立子系统形式出现,从它出现在内核根目录下的crypto/就可以看出其地位了。Crypto实现较为复杂,其主要体现在其OOP的设计思路和高度的对像抽像与封装模型,作者展现了其出色的架构设计水准和面向对像的抽像能力。本文力图从加密框架的重要应用,即IPSec(xfrm)的两个重要协议AH和ESP对加密框架的使用,展现其设计与实现。内核版本:2.6.31.13二、 算法模版1. 模版的基本概念算法模版是加密框架的第一个重要概念。内核中有很多算法是动态生成的,例如cbc(des)算法。内
2、核并不存在这样的算法,它事实上是cbc和des的组合,但是内核加密框架从统一抽像管理的角度。将cbc(des)看做一个算法,在实际使用时动态分配并向内核注册该算法。这样,可以将cbc抽像为一个模版,它可以同任意的加密算法进行组合。算法模版使用结构crypto_template来描述,其结构原型:点击(此处)折叠或打开struct crypto_templatestruct list_head list;/模版链表成员,用于注册struct hlist_head instances;/算法实例链表首部struct module*module;/模块指针struct crypto_instance
3、*(*alloc)(struct rtattr*tb);/算法实例分配void(*free)(struct crypto_instance*inst);/算法实例释放char nameCRYPTO_MAX_ALG_NAME;/模版名称;例如,一个名为cbc的算法模版,可以用它来动态分配cbc(des),cbc(twofish)诸如此类。crypto/algapi.c下包含了模版的一些常用操作。最为常见的就是模版的注册与注销,其实质是对以crypto_template_list为首的链表的操作过程:点击(此处)折叠或打开static LIST_HEAD(crypto_template_list)
4、;intcrypto_register_template(struct crypto_template*tmpl)struct crypto_template*q;interr=-EEXIST;down_write(/遍历crypto_template_list,看当前模板是否被注册list_for_each_entry(q,if(q=tmpl)goto out;/注册之list_add(/事件通告crypto_noTIfy(CRYPTO_MSG_TMPL_REGISTER,tmpl);err=0;out:up_write(returnerr;EXPORT_SYMBOL_GPL(crypto_
5、register_template);注销算法模版,除了模版本身,还有一个重要的内容是处理算法模版产生的算法实例,关于算法实例,后文详述。点击(此处)折叠或打开void crypto_unregister_template(struct crypto_template*tmpl)struct crypto_instance*inst;struct hlist_node*p,*n;struct hlist_head*list;LIST_HEAD(users);down_write(BUG_ON(list_empty(/注销算法模版,并重新初始化模版的list成员list_del_init(/首先
6、移除模版上的所有算法实例list=hlist_for_each_entry(inst,p,list,list)interr=crypto_remove_alg(BUG_ON(err);crypto_noTIfy(CRYPTO_MSG_TMPL_UNREGISTER,tmpl);up_write(/释放模版的所有算法实例分配的内存hlist_for_each_entry_safe(inst,p,n,list,list)BUG_ON(atomic_read(tmpl-free(inst);crypto_remove_final(EXPORT_SYMBOL_GPL(crypto_unregister
7、_template);2. 算法模版的查找点击(此处)折叠或打开crypto_lookup_template函数根据名称,查找相应的模版:struct crypto_template*crypto_lookup_template(constchar*name)return try_then_request_module(_crypto_lookup_template(name),name);_crypto_lookup_template完成实质的模版模找工作,而try_then_request_module则尝试动态插入相应的内核模块,如果需要的话:点击(此处)折叠或打开staTIc stru
8、ct crypto_template*_crypto_lookup_template(constchar*name)struct crypto_template*q,*tmpl=NULL;down_read(/遍历crypto_template_list链,匹备模版名称list_for_each_entry(q,if(strcmp(q-name,name)conTInue;/查找命中,需要对其增加引用,以防止其正在使用时,模块被卸载。完成该操作后返回查找到的模版if(unlikely(!crypto_tmpl_get(q)continue;tmpl=q;break;up_read(return
9、 tmpl;3. 模版的算法实例分配时机模版可以看做一个静态的概念,其只有被动态创建后才具有生命力,本文将模版通过alloc分配创建的算法(对像)称为“实例(instance)”。算法模版的核心作用是,上层调用者构造一个完整合法的算法名称,如hmac(md5),触发模版的alloc动作,为该名称分配一个算法实例,类似于为类实例化一个对像,最终的目的还是使用算法本身。对于xfrm来说,一个典型的算法模版的实例分配触发流程如下所述:xfrm包裹了一层加密框架支持,参后文“ xfrm加密框架”一节,其算法查找函数为xfrm_find_algo,它调用crypto_has_alg函数进行算法的查找,以
10、验证自己支持的算法是否被内核支持,如xfrm支持cbc(des),但此时并不知道内核是否有这个算法(如果该算法首次被使用,则还没有分配算法实例)。crypto_has_alg会调用crypto_alg_mod_lookup完成查找工作,crypto_alg_mod_lookup函数查找不命中,会调用crypto_probing_notify函数进行请求探测:点击(此处)折叠或打开struct crypto_alg*crypto_alg_mod_lookup(constchar*name,u32 type,u32 mask)ok=crypto_probing_notify(CRYPTO_MSG_
11、ALG_REQUEST,larval);请求是通过通知链表来通告的:点击(此处)折叠或打开intcrypto_probing_notify(unsigned long val,void*v)intok;ok=blocking_notifier_call_chain(if(ok=NOTIFY_DONE)request_module(cryptomgr);ok=blocking_notifier_call_chain(return ok;在algboss.c中注册了一个名为cryptomgr_notifier的通告块结构,其通告处理函数为cryptomgr_notify点击(此处)折叠或打开sta
12、tic struct notifier_block cryptomgr_notifier=.notifier_call=cryptomgr_notify,;staticint_init cryptomgr_init(void)return crypto_register_notifier(static void _exit cryptomgr_exit(void)interr=crypto_unregister_notifier(BUG_ON(err);这样,当有算法被使用的时候,会调用通告块的处理函数cryptomgr_notify,因为此时的消息是CRYPTO_MSG_ALG_REQUES
13、T,所以cryptomgr_schedule_probe进行算法的探测:点击(此处)折叠或打开staticintcryptomgr_notify(struct notifier_block*this,unsigned long msg,void*data)switch(msg)caseCRYPTO_MSG_ALG_REQUEST:return cryptomgr_schedule_probe(data);return NOTIFY_DONE;cryptomgr_schedule_probe启动一个名为cryptomgr_probe的内核线程来进行算法模版的探测:点击(此处)折叠或打开stati
14、cintcryptomgr_schedule_probe(struct crypto_larval*larval)/构造param,以供后面使用thread=kthread_run(cryptomgr_probe,param,cryptomgr_probe);cryptomgr_probe完成具体的算法探测过程:点击(此处)折叠或打开staticintcryptomgr_probe(void*data)struct cryptomgr_param*param=data;struct crypto_template*tmpl;struct crypto_instance*inst;interr;
15、/查找算法模版tmpl=crypto_lookup_template(param-template);if(!tmpl)gotoerr;/循环调用模版的alloc函数分配算法实列,并将模版注册之/这里值得注意的是循环的条件,当返回码为-EAGAIN时,会循环再次尝试/这样使用的一个场景后面会分析到doinst=tmpl-alloc(param-tb);if(IS_ERR(inst)err=PTR_ERR(inst);elseif(err=crypto_register_instance(tmpl,inst)tmpl-free(inst);while(err=-EAGAIN/查找中会增加引用,这
16、里已经用完了释放之crypto_tmpl_put(tmpl);if(err)gotoerr;out:kfree(param);module_put_and_exit(0);err:crypto_larval_error(param-larval,param-otype,param-omask);goto out;理解了算法的注册与查找后,再来理解这个函数就非常容易了,其核心在dowhile循环中,包含了算法实例的分配和注册动作。针对每一种算法模版,其alloc动作不尽一致。后文会对xfrm使用的算法模版一一阐述。为什么不把“算法实例”直接称之为“算法”,这是因为实例包含了更多的内容,其由结构s
17、truct crypto_instance可以看出:点击(此处)折叠或打开struct crypto_instancestruct crypto_alg alg;/对应的算法名称struct crypto_template*tmpl;/所属的算法模版struct hlist_node list;/链表成员void*_ctxCRYPTO_MINALIGN_ATTR;/上下文信息指针;内核使用struct crypto_alg描述一个算法(该结构在后文使用时再来分析),可见一个算法实例除了包含其对应的算法,还包含更多的内容。当分配成功后,cryptomgr_probe会调用crypto_regis
18、ter_instance将其注册,以期将来可以顺利地找到并使用它:点击(此处)折叠或打开intcrypto_register_instance(struct crypto_template*tmpl,struct crypto_instance*inst)struct crypto_larval*larval;interr;/对算法进行合法性检查,并构造完整的驱动名称err=crypto_check_alg(if(err)gotoerr;/设置算法内核模块指针指向所属模版inst-alg.cra_module=tmpl-module;down_write(/注册算法实例对应的算法larval=
19、_crypto_register_alg(if(IS_ERR(larval)goto unlock;/成功后,将算法再注册到所属的模版上面hlist_add_head(/设置模版指针inst-tmpl=tmpl;unlock:up_write(err=PTR_ERR(larval);if(IS_ERR(larval)gotoerr;crypto_wait_for_test(larval);err=0;err:returnerr;注册的一个重要工作,就是调用_crypto_register_alg将实例所对应的算法注册到加密框架子系统中。算法注册成功后,上层调用者就可以调用crypto_alg_
20、mod_lookup等函数进行查找,并使用该算法了。三、 HMACMAC(消息认证码)与hash函数非常相似,只是生成固定长度的消息摘要时需要秘密的密钥而已。HAMC是密钥相关的哈希运算消息认证码(keyed-Hash Message Authentication Code),HMAC运算利用哈希算法,以一个密钥和一个消息为输入,生成一个消息摘要作为输出。具体的算法描述详见:http:/baike.baidu/view/1136366?fr=ala0_1。根据HMAC的特点(可以和类似md5、sha等hash算法组合,构造出hmac(md5)这样的算法),Linux 加密框架将其抽像为一个算法
21、模版。本章将假设上层调用者使用了名为hmac(md5)的算法,展示这一算法是如何被构造、初始化及调用以实现数据验证的。1. 算法模版的注册与注销点击(此处)折叠或打开static struct crypto_template hmac_tmpl=.name=hmac,.alloc=hmac_alloc,.free=hmac_free,.module=THIS_MODULE,;点击(此处)折叠或打开staticint_init hmac_module_init(void)return crypto_register_template(点击(此处)折叠或打开static void _exit hm
22、ac_module_exit(void)crypto_unregister_template(模版的注册与注销前文已经描述过了。2. 算法实例的分配当一个算法需要被使用却查找不到的时候,会尝试调用其模版对应分配相应的算法实列,这也适用于hmac,其alloc函数指针指向hmac_alloc:点击(此处)折叠或打开static struct crypto_instance*hmac_alloc(struct rtattr*tb)struct crypto_instance*inst;struct crypto_alg*alg;interr;intds;/类型检查,所属算法必需为hash类型err
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 了解 学习 Linux 加密 框架 设计 实现
链接地址:https://www.31doc.com/p-3372010.html