首页 理论教育 Linux内核安全模块:密钥生命周期分析

Linux内核安全模块:密钥生命周期分析

时间:2023-11-22 理论教育 版权反馈
【摘要】:在数据结构中用flags来标识密钥的生命周期状态。密钥的“死亡”状态有三个,它们略有不同。在发起新进程之前,内核首先分配一个密钥,将密钥的状态设置为“user_construct”。在图16-1的基础上增加两个状态“user_construct”和“negative”就形成了图16-2。图16-1 密钥的基本生命周期图16-2 密钥的生命周期下面看一下代码:request_key.c调用了request_key_and_link:request_key_and_link会尝试查找密钥,如果没有找到,request_key_and_link会调用construct_key_and_link:下面来看construct_key:如果密钥类型中没有特殊规定,函数call_sbin_request_key就会被调用。

Linux内核安全模块:密钥生命周期分析

密钥是动态创建的,它有生命周期,如图16-1所示。在数据结构中用flags来标识密钥的生命周期状态。

用户态进程首先会创建密钥,内核响应用户态进程的请求会生成一个密钥,分配内存。密钥的第二个状态是instantiated,内核将用户态进程提供的输入填入密钥的负载(payload)之中。这时的密钥就可以被用来做加解密使用了。密钥的“死亡”状态有三个,它们略有不同。revoke和invalidate都是由用户态进程发起的请求,内核对invalidate的响应是立即让密钥失效,收回密钥上的资源;内核对revoke的响应也是让密钥失效并收回资源,只是在此之前先调用密钥所属的类型(struct key_type)中定义的一个函数(revoke)。dead状态不是由用户态进程删除密钥导致的,而是由于一种类型(key_type)的密钥失效导致的,一般造成这种状况是因为相关的内核模块被卸载。

密钥的构造由用户态进程发起,密钥的payload数据由用户态进程提供,或者由用户态进程指令内核生成。当内核子系统要用到某个密钥,而这个密钥还不存在怎么办?一种简单的做法是由内核启动一个用户态进程,再由这个进程来填充密钥的payload。在发起新进程之前,内核首先分配一个密钥,将密钥的状态设置为“user_construct”。发起的新进程负责填充密钥的payload。这时,进程有两个选择,一个是立刻提供payload并通知内核将密钥的状态置为“instantiated”;另一个是不能马上提供payload数据,它就通知内核将密钥的状态置为“negative”,以后再提供数据并修改状态。在图16-1的基础上增加两个状态“user_construct”和“negative”就形成了图16-2。

978-7-111-54905-5-Part05-5.jpg

图16-1 密钥的基本生命周期

978-7-111-54905-5-Part05-6.jpg

图16-2 密钥的生命周期

下面看一下代码:

978-7-111-54905-5-Part05-7.jpg

request_key.c调用了request_key_and_link:

978-7-111-54905-5-Part05-8.jpg(www.xing528.com)

978-7-111-54905-5-Part05-9.jpg

request_key_and_link会尝试查找密钥,如果没有找到,request_key_and_link会调用construct_key_and_link:

978-7-111-54905-5-Part05-10.jpg

下面来看construct_key:

978-7-111-54905-5-Part05-11.jpg

如果密钥类型中没有特殊规定,函数call_sbin_request_key就会被调用。call_sbin_request_ key的定义为:

978-7-111-54905-5-Part05-12.jpg

978-7-111-54905-5-Part05-13.jpg

call_sbin_request_key函数定义比较长,上面只保留了核心部分,主要功能是用要实例化的密钥的序列号(key->serial)生成一个描述字符串(desc),用这个描述字符串生成一个钥匙串kering),然后将authkey链接入钥匙串。最后用钥匙串作为参数调用call_usermodehelper_keys call_usermodehelper_keys将会启动一个用户态进程,这个用户态进程负责实例化密钥。

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈