发明内容
本发明的目的是:提供一种基于TPM的Linux内核初始化中的数据结构保护方法及系统,动态保护了Linux内核在初始化阶段的完整性,有效阻止了各种攻击手段,并动态保护了Linux内核在初始化阶段页表、IDT表、GDT表的完整性。
为此,本发明提供了一种基于TPM的Linux内核初始化中的数据结构保护方法,其特征在于,包括:
步骤1,在启动加载器后计算Linux内核的完整性度量值记为Kernel-Integrity-Value1;
步骤2,对所述Kernel-Integrity-Value1进行数字签名并初始化数据结构记为Loader_Secure_Data;
步骤3,将所述Loader_Secure_Data发送到Linux内核中;
步骤4,认证Linux内核的完整性,并对Linux内核进行解压缩;
步骤5,分别对首次初始化页表、初始化GDT表、初始化IDT表进行基于TPM的数据绑定操作;
步骤6,分别对第二次初始化页表、读取GDT表、第二次初始化IDT表进行基于TPM的数据解除绑定操作。
所述步骤1包括:
步骤11,使用TPM的随机数产生器产生一个随机数记为Loader-Random-Value1;
步骤12,把Linux内核加载到内存,用BIOS中断的方法调用TPM的SHA-1引擎计算Linux内核的度量值记为Loader-Measure-Value1,使用TPM扩展功能将该Loader-Measure-value1扩展到PCR寄存器中,使用TPM读取功能将该PCR寄存器的内容读到内存变量中记为Mem_PcrValue;
步骤13,使用SHA-1算法计算Loader-Random-Value1和Mem_PcrValue的连接后的度量值,得到Kernel-Integrity-Value1并将其存储在内存变量中。
所述步骤2包括:
步骤21,使用TPM的RSA引擎产生一个公钥记为RSA_Pubkey和一个私钥记为RSA_Prvikey;
步骤22,将签名操作后的结果保存在内存变量中记为Signed-Kernel-Integrity-Value1;
步骤23,定义所述Loader_Secure_Data,其内包含Signed-Kernel-Integrity-Value1、RSA_Pubkey、Loader-Random-Value1三个域。
所述步骤3包括:
步骤31,在Linux内核空间预先设置一个特殊的空间标志并记为Integrity-Secure-Flag,在这个空间标志后定义一个大小为sizeof的数据结构;
步骤32,采用内存扫描的方法查找到该Integrity-Secure-Flag后,将所述Loader_Secure_Data拷贝到所述Integrity-Secure-Flag后并记为Kernel_Secure_data。
所述步骤4包括:
步骤41,使用扫描内存的方法查找所述Integrity-Secure-Flag后,取出所述Kernel_Secure_data;
步骤42,采用BIOS中断的方法调用TPM的SHA-1引擎计算Linux内核的度量值记为Kernel-Measure-Value2,然后使用SHA-1算法计算SHA-1((Kernel_Secure_data→Loader-Random-Value1)||Kernel-Measure-Value2)后的结果记为Soft-Kernel-Measure-Value2;
步骤43,用所述Kernel_Secure_data的第二个域Kernel_Secure_data→RSA_Pubkey对Kernel_Secure_data的第一个域Kernel_Secure_data→Signed-Kernel-Integrity-Value1进行签名的认证后记为Decrypted_Signed-Kernel-Integrity-Value1;
步骤44,比较所述Soft-Kernel-Measure-Value2与所述Decrypted_Signed-Kernel-Integrity-Value1是否一致,若一致,继续解压linux内核,若不一致,则停机。
所述步骤5包括:
若Linux内核进入到初始化内核页表,则将页目录记为swapper_pg_dir采用TPM_Bind绑定,绑定操作使用Kernel_Secure_data→RSA_Pubkey作为密钥;
若Linux内核进入到初始化GDT表,则将全局描述符记为gdt_table采用TPM_Bind绑定,绑定操作使用作为Kernel_Secure_data→RSA_Pubkey作为密钥;
若将中断描述表记为idt_table采用TPM_Bind绑定,则绑定操作使用Kernel_Secure_data→RSA_Pubkey作为密钥。
所述步骤6具体包括:
若内核函数paging_init()对所述swapper_pg_dir进行写操作,则先进行Bind_pg_data的解除绑定操作,解除绑定使用所述RSA_Pubkey作为解密密钥,若解除绑定操作错误,禁止对swapper_pg_dir的进一步初始化,系统宕机,否则继续初始化;
若内核函数do_basic_setup()中对gdt_table使用函数get_cpu_gdt_table()读取,则先进行Bind_gdt_data的解除绑定操作,解除绑定使用RSA_Pubkey作为解密密钥,若解除绑定操作错误,禁止获取gdt_table,系统宕机,否则继续初始化;
若内核函数trap_init()和init_IRQ()中对idt_table进行写操作,则先进行Bind_idt_data的解除绑定操作,解除绑定使用RSA_Pubkey作为解密密钥,若解除绑定操作错误,禁止对idt_table的进一步初始化,系统宕机,否则继续初始化。
为达到上述目的,本发明另外提供了一种基于TPM的Linux内核初始化中的数据结构保护系统,包括:
完整度量值计算模块,用于在启动加载器后计算Linux内核的完整性度量值记为Kernel-Integrity-Value1;
签名初始化模块,用于对所述Kernel-Integrity-Value1进行数字签名并初始化数据结构记为Loader_Secure_Data;
第一发送模块,用于将所述Loader_Secure_Data发送到Linux内核中;
认证压缩模块,用于认证Linux内核的完整性,并对Linux内核进行解压缩;
绑定模块,分别对首次初始化页表、初始化GDT表、初始化IDT表的进行基于TPM的数据绑定操作;
解除绑定模块,在Linux内核启动的Start_kernel阶段,分别对第二次初始化页表、读取GDT表、第二次初始化IDT表进行基于TPM的数据解除绑定操作。
所述完整度量值计算模块包括:
随机数产生模块,使用TPM的随机数产生器产生一个随机数记为Loader-Random-Value1;
扩展模块,把Linux内核加载到内存,用BIOS中断的方法调用TPM的SHA-1引擎计算Linux内核的度量值记为Loader-Measure-Value1,使用TPM扩展功能将该Loader-Measure-value1扩展到PCR寄存器中,使用TPM读取功能将该PCR寄存器的内容读到内存变量中记为Mem_PcrValue;
第一计算模块,使用SHA-1算法计算Loader-Random-Value1和Mem_PcrValue的连接后的度量值,得到Kernel-Integrity-Value1并将存储在内存变量中。
所述签名初始化模块包括:
产生模块,使用TPM的RSA引擎产生一个公钥记为RSA_Pubkey和一个私钥记为RSA_Prvikey;
保存模块,将签名操作后的结果保存在内存变量中记为Signed-Kernel-Integrity-Value1;
定义模块,定义所述Loader_Secure_Data,其内包含Signed-Kernel-Integrity-Value1、RSA_Pubkey、Loader-Random-Value1三个域。
所述第一发送模块包括:
预先设置模块,在Linux内核空间预先设置一个特殊的空间标志并记为Integrity-Secure-Flag,在这个空间标志后定义一个大小为sizeof的数据结构记为Kernel_Secure_data;
第二发送模块,采用内存扫描的方法查找到该Integrity-Secure-Flag后,将所述Loader_Secure_Data发送到所述Kernel_Secure_data中。
所述认证压缩模块包括:
提取模块,使用扫描内存的方法查找所述Integrity-Secure-Flag后,取出所述Kernel_Secure_data;
第二计算模块,采用BIOS中断的方法调用TPM的SHA-1引擎计算Linux内核的度量值记为Kernel-Measure-Value2,然后使用SHA-1算法计算SHA-1((Kernel_Secure_data→Loader-Random-Value1)||Kernel-Measure-Value2)后的结果记为Soft-Kernel-Measure-Value2;
签名认证模块,用所述Kernel_Secure_data的第二个域Kernel_Secure_data→RSA_Pubkey对Kernel_Secure_data的第一个域Kernel_Secure_data→Signed-Kernel-Integrity-Value1进行签名的认证后记为Decrypted_Signed-Kernel-Integrity-Value1;
第一判断模块,比较所述Soft-Kernel-Measure-Value2与所述Decrypted_Signed-Kernel-Integrity-Value1是否一致,若一致,继续解压Linux内核,若不一致,则停机。
所述绑定模块包括:
第一绑定模块,用于在在Linux内核进入到初始化内核页表之后,将页目录记为swapper_pg_dir采用TPM_Bind绑定,绑定操作使用Kernel_Secure_data→RSA_Pubkey作为密钥;
第二绑定模块,用于在Linux内核进入到初始化GDT表之后,将全局描述符记为gdt_table采用TPM_Bingd绑定,绑定操作使用Kernel_Secure_data→RSA_Pubkey作为密钥;
第三绑定模块,用于将中断描述表记为idt_table采用TPM_Bind绑定,绑定操作使用Kernel_Secure_data→RSA_Pubkey作为密钥。
所述解除绑定模块包括:
第一解除绑定模块,用于在内核函数paging_init()对所述swapper_pg_dir进行写操作之前,进行Bind_pg_data的解除绑定操作,解除绑定使用所述RSA_Pubkey作为解密密钥,若解除绑定操作错误,禁止对swapper_pg_dir的进一步初始化,系统宕机,否则继续初始化;
第二解除绑定模块,用于在内核函数do_basic_setup()中对gdt_table使用函数get_cpu_gdt_table()读取之前,进行Bind_gdt_data的解除绑定操作,解除绑定使用RSA_Pubkey作为解密密钥,若解除绑定操作错误,禁止获取gdt_table,系统宕机,否则继续初始化;
第三解除绑定模块,用于在内核函数trap_init()和init_IRQ()中对idt_table进行写操作之前,进行Bind_idt_data的解除绑定操作,解除绑定使用RSA_Pubkey作为解密密钥,若解除绑定操作错误,禁止对idt_table的进一步初始化,系统宕机,否则继续初始化。
本发明的有益效果在于:对Linux内核镜像本身以及Linux内核初始化过程中加载的内核页表、GDT表、IDT表(包含系统调用表)进行了基于TPM的可信验证、可信数据绑定、可信数字签名等保护操作,避免了一些常见的RootKit对Linux内核在初始化过程中加载的机会,非常适合Linux内核的可信初始化以及当前云计算环境下虚拟机的可信初始化,对于构造可信云平台具有重要的实际意义,具有良好的市场前景和应用价值。
具体如下:
1.克服了现有软件检测工具的不足,使用TPM硬件实时防御,有效的阻止了各种类型的攻击。
2.动态保护了Linux内核在初始化阶段的完整性,有效阻止了背景技术中的攻击手段1)LKM形式的注入;
3.动态保护了Linux内核在初始化阶段页表、IDT表、GDT表的完整性,有效阻止了背景技术中的攻击手段2)、3)描述的入侵手段。
以下结合附图和具体实施例对本发明进行详细描述,但不作为对本发明的限定。
具体实施方式
以GRUB-0.9.7作为启动加载器,Linux-2.6.32内核的初始化为例对本发明的基于TPM的Linux内核初始化中的数据结构保护方法进一步描述。
图1是本发明的基于TPM的Linux内核初始化中的数据结构保护方法流程图。如图1所示,该方法包括:
步骤1,在启动加载器后计算Linux内核的完整性度量值记为Kernel-Integrity-Value1;
步骤2,对所述Kernel-Integrity-Value1进行数字签名并初始化数据结构记为Loader_Secure_Data;
步骤3,将所述Loader_Secure_Data发送到Linux内核中;
步骤4,认证Linux内核的完整性,并对Linux内核进行解压缩;
步骤5,分别对首次初始化页表、初始化GDT表、初始化IDT表的进行基于TPM的数据绑定操作;
步骤6,分别对第二次初始化页表、读取GDT表、第二次初始化IDT表进行基于TPM的数据解除绑定操作。
步骤1,在启动加载器后计算Linux内核的完整性度量值记为Kernel-Integrity-Value1。其实现方法为:
A1.用户获得TPM的使用权,使用TPM的RNG(随机数产生器)产生一个随机数记为Loader-Random-Value1;
本步骤中,使用TPM_TakeOwnership()函数获得TPM的使用权,使用TPM_GetRandom()函数获得随机数。
A2.把Linux内核加载到内存,用BIOS中断的方法调用TPM的SHA-1引擎计算Linux的度量值记为Loader-Measure-Value1,同样使用BIOS中断的方法调用TPM扩展(TPM Extend)功能,将Loader-Measure-value1扩展到指定PCR_Index的PCR寄存器中,使用TPM读取(TPM_PCRRead)功能将指定PCR_Index的PCR寄存器的内容读到Mem_PcrValue;
本步骤中,调用SHA-1引擎的BIOS中断子功能号为0xBB05H,功能号为0x1AH,调用TPM_Extend的BIOS中断子功能号为0xBB04H,功能号为0x1AH,用TPM_PCRRead功能采用PCR_Index为8,即采用PCR8寄存器。
A3.使用软件的SHA-1算法计算Loader-Random-Value1和Mem_PcrValue的连接后的度量值,即计算SHA-1(Loader-Random-Valuel||Mem_PcrValue)的结果,计算完成后的结果存储在内存变量Kernel-Integrity-Value1中。
本步骤中,需要注意的是符号“||”表示连接操作,其含义是将这个符号前后两部分数据连接起来。SHA-1算法是已经公布的算法,具体实施方法不再赘述。
上述的A1,A2,A3步骤在GRUB的Stage2阶段的builtins.c文件的boot_func()中实现。
步骤2,对所述Kernel-Integrity-Value1进行数字签名并初始化数据结构记为Loader_Secure_Data。其实现方法为:
B1.使用TPM的RSA引擎产生一个公钥RSA_Pubkey和一个私钥RSA_Prvikey;
本步骤中,采用命令TPM_CreateEndorsementKeyPair创建RSA_Pubkey和RSA_Prvikey密钥对。
B2.使用TPM的签名操作对Kernel-Integrity-Value1进行数字签名操作,签名操作后的结果保存在Signed-Kernel-Integrity-Value1中,签名的私钥采用B1得到的RSA-Prvikey;
本步骤中,签名操作采用函数TPM_Sign()进行数字签名。
B3.定义数据结构Loader_Secure_Data,其内包含Signed-Kernel-Integrity-Value1、RSA_Pubkey、Loader-Random-Value1三个域;
本步骤操作简单明显,无需赘述。
步骤3,将所述Loader_Secure_Data发送到Linux内核中。其实现方法为:
C1.在Linux内核空间预先设置一个特殊的空间标志Integrity-Secure-Flag,在这个空间标志后定义一个类型为Loader_Secure_Data,大小为sizeof(Loader_Secure_Data)的数据结构;
本步骤中设置空间标志Integrity-Secure-Flag的原因是后续代码能方便找到其后定义的数据结构Kernel_Secure_data。
C2.启动加载器把Linux内核加载到内存时,采用内存扫描的方法查找到该Integrity-Secure-Flag后,将所述Loader_Secure_Data拷贝到所述Integrity-Secure-Flag后并记为Kernel_Secure_data中。
本步骤中在GRUB的stage2阶段的builtins.c文件的boot_func()函数最后阶段实现,实现时定义一个工作指针,从Linux内核加载的起始地址开始扫描,直到找到标志Integrity-Secure-Flag后,使用内存拷贝的方法将Loader_Secure_Data拷贝到C1定义的Kernel_Secure_data中。
步骤4,在Linux内核启动的Setup阶段之后,认证Linux内核的完整性,并对Linux内核进行解压缩。其实现方法为:
D1.使用扫描内存的方法查找C1预设的Integrity-Secure-Flag,找到后取出Integrity-Secure-Flag之后Kernel_Secure_data的数据结构;
本步骤中内存扫描的的实现方法同C2的方法。
D2.在Linux内核解压缩前,采用BIOS中断的方法调用TPM的SHA-1引擎计算Vmlinux的度量值记为Kernel-Measure-Value2,之后使用软件SHA-1算法计算SHA-1((Kernel_Secure_data→Loader-Random-Value1)||Kernel-Measure-Value2)后的结果为Soft-Kernel-Measure-Value2;
本步骤中特别需要注意的是计算Kernel-Measure-Value2时,必须通过SHA-1(Setup.bin||Vmlinux.bin)计算得到。因为在步骤A中对Linux内核的完整性度量值计算时度量对象包含了Setup.bin和Vmlinux.bin两个部分。
D3.用Kernel_Secure_data数据结构的第二个域Kernel_Secure_data→RSA_Pubkey对Kernel_Secure_data的第一个域Kernel_Secure_data→Signed-Kernel-Integrity-Value1进行签名的认证后得到的结果记为Decrypted_Signed-Kernel-Integrity-Value1;
本步骤中签名认证的方法是使用RSA_public_decrypt方法对Signed-Kernel-Integrity-Value1进行解密得到Decrypted_Signed-Kernel-Integrity-Value1;
D4.比较Soft-Kernel-Measure-Value2与Decrypted_Signed-Kernel-Integrity-Value1是否一致,若一致,继续解压Linux内核,否则停机。
注意:上述描述的D1,D2,D3,D4步骤的实施方式可以在文件/arch/x86/boot/compressed/misc.c中定义一个函数attest_kernel()来实现,在文件/arch/x86/boot/compressed/head_32.S中Entry(startup_32)函数的调用calldecompress_kernel之前增加一个call attest_kernel调用。
步骤5,在Linux内核解压缩完成后,分别对首次初始化页表、初始化GDT表、初始化IDT表的进行基于TPM的数据绑定操作。其实现方法为:
E1.在Linux内核进入到ENTRY(startup_32)初始化内核页表之后,将页目录swapper_pg_dir采用TPM_Bind绑定为Bind_pg_data,绑定操作使用Kernel_Secure_data→RSA_Pubkey作为密钥;
E2.在Linux内核进入到ENTRY(startup_32)初始化GDT表之后,将全局描述符gdt_table采用TPM_Bind绑定为Bing_gdt_data,绑定操作使用Kernel_Secure_data→RSA_Pubkey作为密钥;
E3.在Linux内核进入到ENTRY(startup 32)初始化IDT表之后,将中断描述表idt_table采用TPM_Bind绑定为Bind_idt_data,绑定操作使用Kernel_Secure_data→RSA_Pubkey作为密钥;
注意:上述的E1,E2,E3步骤的实施方式可以在文件/arch/x86/kernel/head_32.S中实现。
步骤6,在Linux内核启动的Start_kernel阶段,分别对第二次初始化页表、读取GDT表、第二次初始化IDT表进行基于TPM的数据解除绑定操作。其实现方法为:
F1.内核函数paging_init()对swapper_pg_dir进行写操作之前,进行Bind_pg_data的解除绑定操作,解除绑定使用RSA_Pubkey作为解密密钥,若解除绑定操作错误,禁止对swapper_pg_dir的进一步初始化,系统宕机,否则继续初始化。本步骤中,解除绑定的操作在文件/arch/x86/mm/init_32.c的paging_init()函数中实现。
F2.内核函数do_basic_setup()中对gdt_table使用函数get_cpu_gdt_table()读取之前,进行Bind_gdt_data的解除绑定操作,解除绑定使用RSA_Pubkey作为解密密钥,若解除绑定操作错误,禁止获取gdt_table,系统宕机,否则继续初始化。
本步骤中,get_cpu_gdt_table()函数在/arch/x86/include/asm/desc.h中定义,所以解除绑定的操作可以在这个函数实现的开头部分完成。Linux内核文件/drivers/pnp/pnpbios/bioscalls.c,/drivers/lguest/x86/core.c,/arch/x86/power.c,/arch/x86/kernel/acpi/sleep.c等都要读取gdt_table,所以在get_cpu_gdt_table()函数的定义的/arch/x86/include/asm/desc.h文件中完成,保证了任何读取gdt_table的操作必须首先完成解除绑定操作。
F3.内核函数trap_init()和init_IRQ()中对idt_table进行写操作之前,进行Bind_idt_data的解除绑定操作,解除绑定使用RSA_Pubkey作为解密密钥,若解除绑定操作错误,禁止对idt_table的进一步初始化,系统宕机,否则继续初始化。
本步骤中trap_init()函数位于/arcr/x86/kernel/traps.c中实现,init_IRQ()函数在/arch/x86/kernel/irqinit.c中实现,这两个函数最终都会调用对IDT表进行写操作的函数write_idt_entry(idt_table,...),而函数write_idt_entry(idt_table,...)在/include/asm-x86/desc_32.h中定义,所以在此函数的开头实现解除绑定操作。
图2是本发明的基于TPM的Linux内核初始化中的数据结构保护系统示意图。如图2所示,该系统包括:
完整度量值计算模块100,用于在启动加载器后计算Linux内核的完整性度量值记为Kernel-Integrity-Value1;
签名初始化模块200,用于对所述Kernel-Integrity-Value1进行数字签名并初始化数据结构记为Loader_Secure_Data;
第一发送模块300,用于将所述Loader_Secure_Data发送到Linux内核中;
认证压缩模块400,用于认证Linux内核的完整性,并对Linux内核进行解压缩;
绑定模块500,分别对首次初始化页表、初始化GDT表、初始化IDT表的进行基于TPM的数据绑定操作;
解除绑定模块600,在Linux内核启动的Start_kernel阶段,分别对第二次初始化页表、读取GDT表、第二次初始化IDT表进行基于TPM的数据解除绑定操作。
完整度量值计算模块,用于在启动加载器后计算Linux内核的完整性度量值记为Kernel-Integrity-Value1;
所述完整度量值计算模块100包括:
随机数产生模块,用户获得TPM的使用权,使用TPM的RNG(随机数产生器)产生一个随机数记为Loader-Random-Value1;
本模块中,使用TPM_TakeOwnership()函数获得TPM的使用权,使用TPM_GetRandom()函数获得随机数。
扩展模块,把Linux内核加载到内存,用BIOS中断的方法调用TPM的SHA-1引擎计算Linux的度量值记为Loader-Measure-Value1,同样使用BIOS中断的方法调用TPM扩展(TPM_Extend)功能,将Loader-Measure-value1扩展到指定PCR_Index的PCR寄存器中,使用TPM读取(TPM_PCRRead)功能将指定PCR_Index的PCR寄存器的内容读到Mem_PcrValue;
本模块中,调用SHA-1引擎的BIOS中断子功能号为0xBB05H,功能号为0x1AH,调用TPM_Extend的BIOS中断子功能号为0xBB04H,功能号为0x1AH,用TPM_PCRRead功能采用PCR_Index为8,即采用PCR8寄存器。
第一计算模块,使用软件的SHA-1算法计算Loader-Random-Value1和Mem_PcrValue的连接后的度量值,即计算SHA-1(Loader-Random-Value1||Mem_PcrValue)的结果,计算完成后的结果存储在内存变量Kernel-Integrity-Value 1中。
本模块中,需要注意的是符号“||”表示连接操作,其含义是将这个符号前后两部分数据连接起来。SHA-1算法是已经公布的算法,具体实施方法不再赘述。
上述的三个模块在GRUB的Stage2阶段的builtins.c文件的boot_func()中实现。
签名初始化模块200,用于对所述Kernel-Integrity-Value1进行数字签名并初始化数据结构记为Loader_Secure_Data。该模块包括:
产生模块,使用TPM的RSA引擎产生一个公钥RSA_Pubkey和一个私钥RSA_Prvikey;
本模块中,采用命令TPM_CreateEndorsementKeyPair创建RSA_Pubkey和RSA_Prvikey密钥对。
保存模块,使用TPM的签名操作对Kernel-Integrity-Value1进行数字签名操作,签名操作后的结果保存在Signed-Kernel-Integrity-Value1中,签名的私钥采用产生模块得到的RSA-Prvikey;
本模块中,签名操作采用函数TPM_Sign()进行数字签名。
定义模块,定义数据结构Loader_Secure_Data,其内包含Signed-Kernel-Integrity-Value1、RSA_Pubkey、Loader-Random-Value1三个域;
本模块操作简单明显,无需赘述。
第一发送模块300,用于将所述Loader_Secure_Data发送到Linux内核中。该模块包括:
预先设置模块,在Linux内核空间预先设置一个特殊的空间标志Integrity-Secure-Flag,在这个空间标志后定义一个类型为Loader_Secure_Data,大小为sizeof(Loader_Secure_Data)的数据结构;
本模块中设置空间标志Integrity-Secure-Flag的原因是后续代码能方便找到其后定义的数据结构Kernel_Secure_data。
第二发送模块,启动加载器把Linux内核加载到内存时,采用内存扫描的方法查找到该Integrity-Secure-Flag后,将所述Loader_Secure_Data拷贝到所述Integrity-Secure-Flag后并记为Kernel_Secure_data中。
本模块中在GRUB的stage2阶段的builtins.c文件的boot_func()函数最后阶段实现,实现时定义一个工作指针,从Linux内核加载的起始地址开始扫描,直到找到标志Integrity-Secure-Flag后,使用内存拷贝的方法将Loader_Secure_Data拷贝到预先设置模块定义的Kernel_Secure_data中。
认证压缩模块400,用于认证Linux内核的完整性,并对Linux内核进行解压缩。该模块包括:
提取模块,使用扫描内存的方法查找预先设置模块预设的Integrity-Secure-Flag,找到后取出Integrity-Secure-Flag之后Kernel_Secure_data的数据结构;
本模块中内存扫描的的实现方法同第二发送模块的方法。
第二计算模块,在Linux内核Vmlinux解压缩前,采用BIOS中断的方法调用TPM的SHA-1引擎计算Vmlinux的度量值记为Kernel-Measure-Value2,之后使用软件SHA-1算法计算SHA-1((Kernel_Secure_data→Loader-Random-Value1)||Kernel-Measure-Value2)后的结果为Soft-Kernel-Measure-Value2;
本模块中特别需要注意的是计算Kernel-Measure-Value2时,必须通过SHA-1(Setup.bin||Vmlinux.bin)计算得到。因为在完整度量值计算模块中对Linux内核的完整性度量值计算时度量对象包含了Setup.bin和Vmlinux.bin两个部分。
签名认证模块,用Kernel_Secure_data数据结构的第二个域Kernel_Secure_data→RSA_Pubkey对Kernel_Secure_data的第一个域Kernel_Secure_data→Signed-Kernel-Integrity-Value1进行签名的认证后得到的结果记为Decrypted_Signed-Kernel-Integrity-Value1;
本模块中签名认证的方法是使用RSA_public_decrypt方法对Signed-Kernel-Integrity-Value1进行解密得到Decrypted_Signed-Kernel-Integrity-Value1;
第一判断模块,比较Soft-Kernel-Measure-Value2与Decrypted_Signed-Kernel-Integrity-Value1是否一致,若一致,继续解压Linux内核,否则停机。
注意:上述描述的四个模块的实施方式可以在文件/arch/x86/boot/compressed/misc.c中定义一个函数attest kernel()来实现,在文件/arch/x86/boot/compressed/head_32.S中Entry(startup_32)函数的调用calldecompress_kernel之前增加一个call attest_kernel调用。
绑定模块500,分别对首次初始化页表、初始化GDT表、初始化IDT表的进行基于TPM的数据绑定操作。该模块包括:
第一绑定模块,在Linux内核进入到ENTRY(startup_32)初始化内核页表之后,将页目录swapper_pg_dir采用TPM_Bind绑定为Bind_pg_data,绑定操作使用Kernel_Secure_data→RSA_Pubkey作为密钥;
第二绑定模块,在Linux内核进入到ENTRY(startup_32)初始化GDT表之后,将全局描述符gdt_table采用TPM_Bingd绑定为Bind_gdt_data,绑定操作使用Kernel_Secure_data→RSA_Pubkey作为密钥;
第三绑定模块,在Linux内核进入到ENTRY(startup_32)初始化IDT表之后,将中断描述表idt_table采用TPM_Bind绑定为Bind_idt_data,绑定操作使用Kernel_Secure_data→RSA_Pubkey作为密钥;
注意:上述三个模块的实施方式可以在文件/arch/x86/kernel/head_32.S中实现。
解除绑定模块,在内核启动的Start_kernel阶段,分别对第二次初始化页表、读取GDT表、第二次初始化IDT表进行基于TPM的数据解除绑定操作。该模块包括:
第一解除绑定模块,内核函数paging_init()对swapper_pg_dir进行写操作之前,进行Bind_pg_data的解除绑定操作,解除绑定使用RSA_Pubkey作为解密密钥,若解除绑定操作错误,禁止对swapper_pg_dir的进一步初始化,系统宕机,否则继续初始化。本模块中,解除绑定的操作在文件/arch/x86/mm/init_32.c的paging_init()函数中实现。
第二解除绑定模块,内核函数do_basic_setup()中对gdt_table使用函数get_cpu_gdt_table()读取之前,进行Bind_gdt_data的解除绑定操作,解除绑定使用RSA_Pubkey作为解密密钥,若解除绑定操作错误,禁止获取gdt_table,系统宕机,否则继续初始化。
本模块中,get_cpu_gdt_table()函数在/arch/x86/include/asm/desc.h中定义,所以解除绑定的操作可以在这个函数实现的开头部分完成。Linux内核文件/drivers/pnp/pnpbios/bioscalls.c,/drivers/lguest/x86/core.c,/arch/x86/power.c,/arch/x86/kernel/acpi/sleep.c等都要读取gdt_table,所以在get_cpu_gdt_table()函数的定义的/arch/x86/include/asm/desc.h文件中完成,保证了任何读取gdt_table的操作必须首先完成解除绑定操作。
第三解除绑定模块,内核函数trap_init()和init_IRQ()中对idt_table进行写操作之前,进行Bind_idt_data的解除绑定操作,解除绑定使用RSA_Pubkey作为解密密钥,若解除绑定操作错误,禁止对idt_table的进一步初始化,系统宕机,否则继续初始化。
本模块中trap_init()函数位于/arcr/x86/kernel/traps.c中实现,init_IRQ()函数在/arch/x86/kernel/irqinit.c中实现,这两个函数最终都会调用对IDT表进行写操作的函数write_idt_entry(idt_table,...),而函数write_idt_entry(idt_table,...)在/include/asm-x86/desc_32.h中定义,所以在此函数的开头实现解除绑定操作。
当然,本发明还可有其它多种实施例,在不背离本发明精神及其实质的情况下,熟悉本领域的技术人员可根据本发明作出各种相应的改变和变形,但这些相应的改变和变形都应属于本发明权利要求的保护范围。