具体实施方式
为了使本技术领域的人员更好地理解本说明书中的技术方案,下面将结合本说明书实施例中的附图,对本说明书实施例中的技术方案进行清楚、完整地描述,显然,所描述的实施例仅仅是本说明书一部分实施例,而不是全部的实施例。基于本说明书中的实施例,本领域普通技术人员在没有作出创造性劳动前提下所获得的所有其他实施例,都应当属于本说明书保护的范围。
请参见图1,图1是一示例性实施例提供的一种基于可信安全区的请求处理方法的流程图。图2是一示例性实施例提供的一种可信安全区的示意图,如图2所示,所述可信安全区包括第一安全等级的内存段与第二安全等级的内存段,其中,第一安全等级的内存段包括用户数据段与用户程序段,第二安全等级的内存段包括备份数据段与重置程序段,第一安全等级的合法访问范围包括第一安全等级的内存段中的至少一部分内存地址;如图1所示,该方法包括:
S102:响应于任务请求,执行所述重置程序段中的可信安全区重置函数,将所述备份数据段中存储的内存备份覆盖至第一安全等级的合法访问范围对应的内存空间,所述内存备份包括用于覆盖至所述用户数据段的用户数据段备份。
在本说明书实施例中,可信安全区中的程序包括用户目标程序与系统目标程序,其中,用户目标程序由用户源程序编译得到,而系统目标程序由系统源程序编译得到。由于用户源程序是由用户进行编写的自定义程序,因此其被编译成用户目标程序并加载进可信安全区后会给可信安全区带来一定的安全风险;相比之下,系统源程序则由可信安全区的开发者编写,其编译得到的系统目标程序理论上不存在安全风险。于是,为了规避用户目标程序可能对可信安全区带来的安全风险,本说明书实施例采用了将可信安全区按照安全等级分段的安全策略,该安全策略规定处于低安全等级的内存段中的程序无法访问相对更高的安全等级的内存段中的内存空间,而处于高安全等级的内存段中的程序则可以访问到相对较低的安全等级的内存段中的内存空间。在这种安全策略的指导之下,通过将用于加载用户目标程序的用户程序段设置于最低安全等级(第一安全等级)的内存段中,同时将其他系统目标程序与敏感数据段设置于相对较高的安全等级的内存段中,从而使得存在安全风险的用户目标程序只能访问处于第一安全等级的内存段中的部分内存空间(称为第一安全等级的合法访问范围)。例如图2中所示的第一安全等级的内存段中的栈内存段、堆内存段和用户数据段均可以被用户目标程序所正常使用,然而用户目标程序则无法正常访问到除第一安全等级的合法访问范围此之外的所有内存空间,从而保护了系统目标程序与敏感数据段免受用户目标程序的攻击。
本说明实施例所涉及的系统目标程序包括用于执行可信安全区重置逻辑的可信安全区重置函数,该可信安全区重置函数具体被设置于第二安全等级的内存段中的重置程序段,这意味着可信安全区重置函数可以正常对第一安全等级的内存段中的内存空间进行访问和修改,因此不会影响可信安全区重置函数针对于第一安全等级的内存段中存在安全风险的内存空间(即第一安全等级的合法访问范围对应的内存空间)的重置过程的正常实施。具体而言,在可信安全区的接口函数(接口函数属于系统目标程序)接收到来源于可信安全区外部的用于请求执行可信计算任务的任务请求时,需要首先触发重置可信安全区的过程以为执行后续的可信计算任务提供一个清洁的任务执行环境,此时接口函数会调用并执行重置程序段中的可信安全区重置函数。可信安全区重置函数在执行过程中,会将所述备份数据段中存储的内存备份覆盖至第一安全等级的合法访问范围对应的内存空间,使得第一安全等级的合法访问范围的内存空间被完全重置为用户源程序编译完成时的初始内存状态,完成重置可信安全区的过程。本说明书实施例所涉及的第一安全等级的合法访问范围至少包括第一安全等级的内存段中的用户数据段。
需要注意的是,用户源程序在被编译为用户目标程序时,不仅在指令层面将高级/汇编语言编译为了机器语言(编译得到的机器码集合构成了用户目标程序),并将用户目标程序加载至用户程序段,同时也需要申请内存空间以存放程序涉及的数据变量,即这些在用户源程序编译后初始化或未初始化的数据变量被存放至了第一安全等级的内存段中的用户数据段,而本说明书实施例所涉及的内存备份中包括的用于覆盖至所述用户数据段的用户数据段备份,就包含有在用户源程序编译完成时用户数据段的内存状态。
在第一安全等级的合法访问范围还包括第一安全等级的内存段中的用户程序段的情况下,内存备份还可以包括用于覆盖至所述用户程序段的用户程序段备份,该用户程序段备份是指在用户源程序编译完成时用户代码段的内存状态,也即刚编译完毕时得到的初始状态下的用户目标程序。在本说明书实施例中,由于用户目标程序可以访问和修改用户程序段,可能会对包含在其中的自身代码进行修改从而带来较大的安全风险,因此在对可信安全区进行重置的过程中,还可以将用户程序段备份覆盖至用户程序段对应的内存空间,从而使得用户目标程序恢复到刚编译完毕时的初始状态,以清空重置前用户程序段可能存在的安全风险。
除此之外,本说明书实施例所涉及的内存备份还包括在用户源程序编译完成时栈内存段与堆内存段的内存状态,以用于在重置过程中覆盖至当前的债内存段与堆内存段。由于通常情况下栈内存段与堆内存段的内存状态在用户源程序编译完成时为空,因此在执行可信安全区重置函数并完成重置可信安全区的过程之后,栈内存段与堆内存段中的数据会被清空。本说明书实施例所涉及的用户数据段可以包括data段与bss段,其中,对应于用户源程序编译后得到的已初始化的全局变量保存在data 段中,而未初始化的全局变量则保存在bss段中。
在本说明书实施例中,还包括:响应于备份请求或者在所述可信安全区完成冷启动的情况下,执行所述重置程序段中的可信安全区备份函数,将第一安全等级的合法访问范围中的数据作为所述内存备份存储至所述备份数据段。如前所述,备份数据段中存储的内存备份具体为第一安全等级的合法访问范围的内存空间在用户源程序编译完成时的初始内存状态,而该内存备份其实是通过执行重置程序段中的可信安全区备份函数而被存储至备份数据段中。具体而言,在接口程序接收到来源于可信安全区外部的用于调用可信安全区备份函数的备份请求时,或者系统启动程序(属于系统目标程序)响应于可信安全区冷启动完成时(冷启动包括将用户源程序和系统源程序编译为用户目标程序与系统目标程序并被加载至可信安全区中的过程),都会触发调用并执行可信安全区备份函数。可信安全区备份函数在执行过程中,会将第一安全等级的合法访问范围中的数据作为所述内存备份复制并存储至所述备份数据段中,使得当前的第一安全等级的合法访问范围的内存空间的内存状态被完全保存起来以供可信安全区重置函数后续调用。
在本说明书实施例中,所述将所述备份数据段中存储的内存备份覆盖至第一安全等级的合法访问范围对应的内存空间,包括:启用用户权限硬件指令,并通过所述用户权限硬件指令为第一安全等级的合法访问范围对应的内存空间重新分配内存访问权限;将所述备份数据段中存储的内存备份覆盖至第一安全等级的合法访问范围对应的内存空间,并在完成后禁用所述用户权限硬件指令。本说明书实施例所涉及的可信安全区enclave基于Intel SGX(Intel Software Guard Extensions,英特尔软件保护扩展)技术栈所实现,本说明书实施例所涉及的用户权限硬件指令(ENCLU)具体是指Intel SGX中定义的用于指导修改可信安全区内存权限的原生指令,由于该指令会对可信安全区的机密性产生影响,因此除非必要的情况我们不希望该指令能够被随意调用,特别是需要禁止该指令被用户目标程序所调用。在将内存备份覆盖至第一安全等级的合法访问范围对应的内存空间时,由于需要重新分配内存权限因此需要调用用户权限硬件指令(例如用于扩展Enclave现有内存范围的EMODPE指令),因此在这种情况下我们在需要在系统层面提前启用用户权限硬件指令,从而使得可信安全区的重置过程能够正常实现。而在可信安全区完成重置之后,为了避免用户目标程序使用用户权限硬件指令对可信安全区进行攻击,可以在每次完成可信安全区重置之后禁用所述用户权限硬件指令。具体而言,可以通过在可信安全区重置函数中定义一个针对是否启用用户权限硬件指令的全局保险值,在可信安全区重置函数的覆盖重置逻辑之前加入一个将该全局保险值设置为启用状态的逻辑,同时在可信安全区重置函数的覆盖重置逻辑之后加入一个将该全局保险值设置为禁用状态的逻辑。另外,还需要对每个用户权限硬件指令对应的调用条件进行修改,以使在其在全局保险值为启用状态而被调用的情况下正常执行,而在全局保险值为禁用状态而被调用的情况下不执行并返回错误。
在本说明书实施例中,接口函数在接收到任务请求后,还会检查可信安全区中是否存在尚未执行完毕的可信计算任务。如果不存在则可以继续调用并执行可信安全区重置函数,如存在则可以进行等待,直到当前正在执行的可信计算任务执行完毕后,再调用并执行可信安全区重置函数,从而可以避免正在执行的可信计算任务可以完整执行而不会被任务请求所打断。另外,除了响应于任务请求而触发调用并执行可信安全区重置函数之外,接口程序也可以在接收到当前正在执行的可信计算任务执行完毕后返回的执行结果时触发调用并执行可信安全区重置函数,这样一来就可以在后续接收到新的任务请求后无需再次进行重置可信安全区的过程,而可以直接调用用户目标程序执行任务请求对应的可信计算任务。
S104:在所述可信安全区重置函数执行完成后,执行所述用户程序段中由用户源程序编译得到的用户目标程序;其中,所述用户源程序中的内存访问指令被编译为所述用户目标程序中相应的安全内存访问指令,所述安全内存访问指令对应的访存地址属于第一安全等级的合法访问范围。
在本说明书实施例中,接口函数接收到任务请求后,首先调用并执行重置程序段中的可信安全区重置函数,然后在进一步接收到可信安全区重置函数的返回值后,可以确定所述可信安全区重置函数执行完成,于是接下来便可以开始执行所述任务请求对应的可信计算任务。由于执行可信计算任务的模块为用户目标程序,因此接口函数可以进一步调用并执行用户程序段中用户目标程序,调用时可以将所述任务请求中的一些必要的输入参数作为调用参数引入用户目标程序的执行过程。
在本说明书实施例中,“处于低安全等级的内存段中的程序无法访问相对更高的安全等级的内存段中的内存空间,而处于高安全等级的内存段中的程序则可以访问到相对较低的安全等级的内存段中的内存空间”的安全策略实际上是通过编译器技术实现的。例如,为了使第一安全等级的内存段中的用户目标程序只能访问到第一安全等级的合法访问范围,需要在将用户源程序编译为用户目标程序的过程中,通过编译器技术来改变传统编译过程中的指令转换规则,使得改变后的指令转换规则用于指导将所述用户源程序中的内存访问指令编译为所述用户目标程序中相应的安全内存访问指令,并确保用户目标程序中的安全内存访问指令对应的访存地址属于第一安全等级的合法访问范围。由此一来,用户目标程序中所有的访存操作(包括读取操作与写入操作)都会被限制在第一安全等级的合法访问范围之内,而无法访问到第二安全等级及其以上安全等级的内存段对应的内存空间。又例如,为了确保第二安全等级的内存段中的可信安全区重置函数在执行时能够完成重置过程,则必然要求其能够正常访问第一安全等级的内存段。因此,在将系统源程序编译为系统目标程序的过程中,同样可以通过编译器技术来改变传统的指令转换规则,使得改变后的指令转换规则用于指导将系统源程序中的内存访问指令编译为系统目标程序中相应的安全内存访问指令,并确保可信安全区重置函数中的安全内存访问指令对应的访存地址属于第二安全等级的合法访问范围,由于第二安全等级的合法访问范围包括第一安全等级的内存段以及备份数据段,因此可信安全区重置函数能够正常完成可信安全区的重置过程。
用户源程序中的一个内存访问指令本质上为一个高级/汇编语言的编程语句,所述用户目标程序中的一个安全内存访问指令本质上是由一个或多个机器码构成的机器码集合。以用户源程序是汇编语言为例,如果按照传统编译过程中的指令转换规则,用户源程序中的一个内存访问指令将被编译为一个机器码;而如果按照本说明书实施例所涉及的改变后的指令转换规则,则用户源程序中的一个内存访问指令将被编译包含一个或多个机器码的安全内存访问指令,并且安全内存访问指令内蕴含的操作逻辑与通过传统编译得到的一个机器码所蕴含的操作逻辑不同,具体体现为:在内存访问指令对应的原始访问地址不属于第一安全等级的合法访问范围的情况下,当其被编译为安全内存访问指令后,其蕴含操作逻辑将发生变化,即安全内存访问指令将不再访问原始访问地址,而是访问一个属于第一安全等级的合法访问范围内的地址。不难发现,通过本说明书实施例所涉及的改变后的指令转换规则,使得每个编译得到的安全内存访问指令相较于编译前的内存访问指令其蕴含的操作逻辑发生了实质性变化,而这种变化正是使得安全内存访问指令的访存地址可以被限制在某一个合法访问范围的原因。由于汇编指令与机器码是一一对应的,这意味着如果安全内存访问指令包含多个机器码,则将安全内存访问指令反编译为汇编语言时可能得到多个汇编指令,也即通过编译实现改变内存访问指令其蕴含的操作逻辑的方法具体可能是通过内存访问指令内蕴含的操作逻辑所实现的。通过本说明书实施例所涉及的编译方法,能够消除由用户编写的用户源程序在源码层面的越界访存风险(越界访存风险是指访问了除规定的合法访问范围之外的内存空间),将具有越界访存风险的用户源程序净化为了不具有越界访存风险的用户目标程序。
在本说明书实施例中,还包括:响应于所述任务请求,将执行所述用户目标程序所生成的所述任务请求对应的执行结果返回至所述任务请求的发起方。在用户目标程序执行完毕后,接口程序将接收到调用用户目标程序所返回的执行结果,该执行结果即为所述任务请求对应的可信计算任务的执行结果,此时接口程序可以将该执行结果返回给处于可信安全区外部的、所述任务请求对应的发起方,至此可信安全区就完成了一次完整执行可信计算任务的全过程。
本说明书实施例提供了一种可信安全区的安全重置方法,通过将可信安全区分为不同安全等级的内存段,并将由用户编写的用户源程序编译得到的用户目标程序置于第一安全等级的内存段中,由于用户源程序中的内存访问指令被编译为用户目标程序中相应的安全内存访问指令之后,该安全内存访问指令对应的访存地址属于第一安全等级的合法访问范围,这使得用户目标程序只能访问到第一安全等级的合法访问范围的内存空间,从而避免用户目标程序作恶,通过修改其他安全等级的内存段中的程序或数据从内部破坏可信安全区的安全性。例如,用户目标程序无法修改处于第二安全等级的内存段中的内存备份或可信安全区重置函数,因此可以确保每次利用可信安全区重置函数对用户数据段进行重置的过程不会被已经运行在可信安全区中的用户目标程序所影响,即包括可信安全区重置函数在内的、处于第一安全等级的合法访问范围之外的组件都可以在可信安全区重置后持续复用。而对于可信安全区中用户目标程序所能够访问和修改的第一安全等级的合法访问范围对应的内存空间,则在执行可信安全区重置函数过程中通过内存备份对这部分内存空间进行覆盖,即对第一安全等级的合法访问范围对应的内存空间进行完全重置。不难发现,本说明书实施例所实现的可信安全区的安全重置方法本质上也属于一种热启动方法,然而相较于传统的热启动,本说明书实施例实现了只有传统的冷启动才能实现的消除安全隐患的效果,从而兼顾了安全性与效率。具体而言,由于持续复用的第二安全等级及其以上安全等级的内存段不会受到用户目标程序的攻击,因此可以确保持续复用的重置前组件的安全性,特别是执行重置过程的可信安全区重置函数本身的安全性,这维持了系统的自洽性。同时,通过将存在安全风险的第一安全等级的合法访问范围对应的内存空间进行完全重置,可以确保重置后的可信安全区不会继承重置前的可信安全区中的风险,使得即使可信安全区受到用户目标程序的攻击也可以脱离被攻击的状态。
可选的,所述可信安全区还包括第三安全等级的内存段,第三安全等级的内存段包括密钥数据段与证明程序段,所述方法还包括:
响应于程序证明请求,执行所述证明程序段中的嵌套证明函数,基于所述密钥数据段中存储的嵌套证明私钥对待证明数据进行签名以生成可信程序证明,所述待证明数据包括所述用户程序段和/或重置程序段中的数据;
将所述可信程序证明提供至所述程序证明请求的发起方,并接收在所述发起方确认所述可信程序证明验证通过的情况下发送的所述任务请求。
在本说明书实施例中,可信安全区中还包括有第三安全等级的内存段,该内存段中加载有属于系统目标程序的嵌套证明函数,且为了确保嵌套证明函数能够正常实现相应的嵌套证明过程,第三安全等级低合法访问范围包括密钥数据段以及第一安全等级、第二安全等级的内存段。对于任意可信安全区外部的验证方,其都可以通过向可信安全区发起程序证明请求以验证可信安全区内部的程序的完整性,例如,任务请求的发起方也可以同时作为验证方,在验证可信安全区的程序完整性后再向可信安全区发起任务请求,从而可以确保可信安全区可以按照预期规范地执行可信计算任务。具体而言,任务请求的发起方可以在发起任务请求之前,首先向可信安全区发起程序证明请求。由可信安全区中的接口程序接受该程序证明请求后,调用并执行证明程序段中的嵌套证明函数,并在嵌套证明函数返回相应的可信程序证明后,将可信程序证明提供至程序证明请求的发起方也即后续任务请求的发起方。程序证明请求的发起方在对可信程序证明验证通过的情况下,向可信安全区发起任务请求。嵌套证明函数在执行时用于:基于所述密钥数据段中存储的嵌套证明私钥对待证明数据进行签名以生成可信程序证明,向调用点返回该可信程序证明。所述待证明数据包括所述用户程序段和/或重置程序段中的数据,也即用户目标程序和/或可信安全区重置函数,在具体实施时,待证明数据也可以是用户目标程序和/或可信安全区重置函数对应的哈希值。
而程序证明请求的发起方则可以通过事先公开的嵌套证明公钥对所述可信程序证明进行验签,在验签成功后就可以确定该可信程序证明来源可信,由此进一步通过程序完整性检验,在事先公开的用户目标程序和/或可信安全区重置函数对应的哈希值与所述待证明数据中包含的哈希值比对一致的情况下,确认所述用户程序段和/或重置程序段中运行的程序未经篡改。此时程序证明请求的发起方再向可信安全区发起任务请求,就可以确保可信安全任务对应的可信安全区重置过程与用户目标程序执行过程均可在预期下规范地进行。
在传统的远程认证机制中,是由一个专门用于签名的可信安全区(称为QuotingEnclave)使用CPU私钥对待检验的可信安全区中的全部程序进行签名以生成可信程序证明(称为Quote),由于验证方没有掌握对应的CPU公钥无法验证该可信程序证明,因此需要将该可信程序证明转交给远程认证服务器来验证,最终验证方在确定远程认证服务器对该可信程序证明验证成功的情况下,就可以确定该可信程序证明来源可信,并进一步通过程序完整性检验来确认该可信程序证明来源的可信安全区中的程序未经篡改。而在本说明书实施例中,不同于传统的远程认证机制,是由可信安全区中处于第三安全等级的内存段中的嵌套证明函数来对可信安全区自身中处于第一或第二安全等级的内存段中的程序进行签名,由于嵌套证明公钥可以进行公开,因此作为验证方可以对独立地对可信程序证明进行验证,而无需借助远程认证服务器的支持,大大提高了验证方验证程序完整性的效率与成本。
在本说明书实施例中,所述嵌套证明私钥由密钥管理服务器在确认所述可信安全区通过远程认证服务器的远程认证的情况下分配至所述可信安全区中的所述密钥数据段。如前所述,密钥数据段中存储有嵌套证明私钥,该私钥可以是由作为验证方的密钥管理服务器通过传统的远程认证机制,在验证包括证明内存段中的嵌套证明函数在内的可信安全区整体的程序完整性之后,可以向可信安全区分配该嵌套证明私钥,同时向外界公开该嵌套证明私钥对应的嵌套证明公钥,以用于完成后续基于嵌套证明函数的程序完整性验证过程。
在本说明书实施例中,所述可信安全区包括不同安全等级的内存段,所述不同安全等级至少包括第一安全等级与第二安全等级,其中,任一安全等级的合法访问范围包括所述任一安全等级的内存段中的至少一部分内存地址以及低于所述任一安全等级的内存段;
所述可信安全区中的程序包括所述用户目标程序与由系统源程序编译得到的系统目标程序,所述系统目标程序处于第二安全等级及其以上安全等级的内存段中,所述系统目标程序包括所述可信安全区重置函数;所述系统源程序中的内存访问指令被编译为所述系统目标程序中相应的安全内存访问指令,其中,所述任一安全等级的内存段中的安全内存访问指令对应的访存地址属于所述任一安全等级的合法访问范围。
与用户源程序被编译为用户目标程序的过程类似,在将系统源程序编译为系统目标程序的过程中,也可以采用本说明书实施例所涉及的编译方法。具体而言,是将所述系统源程序中的内存访问指令编译为所述系统目标程序中相应的安全内存访问指令,并确保处于任一安全等级的内存段中的某一系统目标程序中的安全内存访问指令对应的访存地址属于所述任一安全等级的合法访问范围。通过本说明书实施例所涉及的编译方法,能够消除系统源程序在源码层面的越界访存风险,将具有越界访存风险的系统源程序净化为了不具有越界访存风险的系统目标程序。以图2所示的可信安全区为例,图2中处于第二安全等级的内存段的可信安全区重置函数中包含的安全内存访问指令仅能够访问备份数据段以及第一安全等级的内存段,而处于第三安全等级的内存段的嵌套证明函数中包含的安全内存访问指令则能够访问密钥数据段、第一安全等级的内存段以及第二安全等级的内存段。
在本说明书实施例中,所述可信安全区定义有全局合法访问范围,所述全局合法访问范围在通过合法调用逻辑跳转至所述任一安全等级的内存段时被设置为所述任一安全等级的合法访问范围,否则被设置为第一安全等级的合法访问范围;所述任一安全等级的内存段中的安全内存访问指令对应的访存地址属于所述全局合法访问范围。在本说明书实施例中,为可信安全区定义了一个全局合法访问范围用于限制同一时刻下可信安全区中所有安全内存访问指令对应的访存地址,该全局合法访问范围并非固定值,而是可以根据可信安全区中的程序运行情况进行相应的改变,其可以改变的取值包括每个安全等级的合法访问范围。如前所述,本说明书实施例通过编译过程修改了源程序中的内存访问指令蕴含的操作逻辑,使编译得到的目标程序中相应的安全内存访问指令对应的访存地址被引导至全局合法访问范围之内。然而目标程序被加载进可信安全区后,却可以导致来自不同安全等级的内存段中安全内存访问指令所对应的访问地址属于不同的合法访问范围的现象,这并非是通过在编译过程中为拟加载至不同安全等级的内存段中安全内访问指令设置不同的操作逻辑实现的,事实上在编译过程中,无论是用户源程序还是系统源程序中的内存访问指令,最终都被按照统一的指令转换规则转换为了蕴含相同操作逻辑的安全内存访问指令,也即所有被加载至可信安全区中的安全内存访问指令对应的访存地址均属于所述全局合法访问范围。之所以可以产生任一安全等级的内存段中的安全内存访问指令对应的访存地址属于所述任一安全等级的合法访问范围的现象,是因为在通过合法调用逻辑由第x安全等级的内存段的程序跳转至第y安全等级的内存段时,全局合法访问范围被设置为第y安全等级的合法访问范围。因此,可信安全区中运行的程序只要是在合法调用逻辑下,就可以实现:虽然所有安全内存访问指令蕴含的操作逻辑相同,都是将实际访存地址限制在全局合法访问范围之内,但处于不同安全等级的内存段中的安全内存访问指令却具有实际上并不相同的合法访问范围。
通过本说明书实施例,可以限制不同安全等级的内存段中的程序之间通过非法调用逻辑进行跳转时,由于全局合法访问范围并未改变,因此从低安全等级的内存段随意跳转到高安全等级的内存段后将因为访存地址的限制从而无法正常执行高安全等级的内存段中的安全内存访问指令。例如,第一安全等级的内存段中的用户目标程序通过自定义的跳转指令等非法调用逻辑跳转至第二安全等级中的内存段的某个指令后,如果没有遇到安全内存访问指令将会正常继续执行(由于没有访问内存因此不会泄露信息或修改数据,安全风险较小),但如果一旦遇到安全内存访问指令,则由于此时的全局合法访问范围依旧是第一安全等级的合法访问范围,因此此时执行的安全内存访问指令虽然其位置处于第二安全等级的内存段中,但其实际的访存地址却会被限制在全局合法访问范围即第一安全等级的合法访问范围之中,从而使得从第一安全等级的内存段中非法跳转到第二安全等级的内存段后,其后续执行的安全内存访问指令依旧无法影响第一安全等级的合法访问范围之外的内存空间,从而减少了因非法调用逻辑而产生的系统安全风险。
在本说明书实施例中,合法调用逻辑主要是指通过所述系统目标程序中的边界修改函数实现的调用逻辑,当可信安全区中的某一程序在运行过程中需要调用处于不同安全等级(特别是更高安全等级)的内存段中的被调用函数时,都需要首先通过Ecall指令来调用边界修改函数实现合法的调用过程。该边界修改函数在执行时用于:更改全局合法访问范围到实际需要调用执行的被调用函数所处内存段的安全等级的合法访问范围,再调用至该被调用函数执行。同时,在被调用函数执行完毕后,还会将全局合法访问范围恢复为修改前的数值,并跳转至边界修改函数的调用点处继续执行后续指令。
可选的,低安全等级的内存段的内存地址高于高安全等级的内存段,任一安全等级的合法访问范围为高于所述任一安全等级的边界地址的地址范围,所述任一安全等级的边界地址属于所述任一安全等级的内存段,所述全局合法访问范围为高于边界寄存器中存储的边界地址,所述合法调用逻辑包括通过所述系统目标程序中的边界修改函数实现的调用逻辑;
执行属于所述系统目标程序且处于所述任一安全等级的内存段中的任一系统函数,包括:
调用所述边界修改函数,将所述边界寄存器中存储的原边界地址修改为所述任一安全等级的边界地址;
在所述边界修改函数中调用执行所述任一系统函数,并在执行完成所述任一系统函数后,将边界寄存器中存储的边界地址修改为所述原边界地址。
图2中所示的可信安全区中各内存段的内存地址自下而上越来越高,从而确保低安全等级的内存段的内存地址高于高安全等级的内存段,即第一安全等级的内存段的内存地址高于第二安全等级的内存段的内存地址,而第二安全等级的内存段的内存地址高于第三安全等级的内存段的内存地址。在本说明书实施例中,通过设置不同安全等级的边界地址来定义不同安全等级的合法访问范围,具体而言,任一安全等级的合法访问范围为高于所述任一安全等级的边界地址的地址范围,从而使任一安全等级的合法访问范围包括低于所述任一安全等级的内存段。同时,为使任一安全等级的合法访问范围包括所述任一安全等级的内存段中的至少一部分内存地址,则需要确保任一安全等级的边界地址属于所述任一安全等级的内存段且高于该边界地址的内存空间至少包含一个数据段。另外,所述全局合法访问范围由边界寄存器中的边界地址所定义,具体为高于边界寄存器中存储的边界地址。
如前所述,在需要调用属于所述系统目标程序且处于所述任一安全等级的内存段中的任一系统函数之前,需要通过合法调用逻辑进行调用。也即首先调用并执行所述边界修改函数,边界修改函数在执行时用于:将所述边界寄存器中存储的原边界地址修改为所述任一安全等级的边界地址,同时调用并执行所述任一系统函数,并在执行完成所述任一系统函数后,将边界寄存器中存储的边界地址修改为所述原边界地址,以完成针对所述任一系统函数的合法调用逻辑。通过本说明实施例,可以使得通过合法调用逻辑所调用的系统函数可以被正常执行,而通过除合法调用逻辑之外的非法调用逻辑所调用的系统函数无法正常执行,从而减少了因非法调用逻辑而产生的系统安全风险。
可选的,所述任一安全等级的内存段包括相应的数据段与内存地址低于该数据段的程序段,所述任一安全等级的边界地址用于分隔所述任一安全等级的内存段中的数据段与程序段。由此一来,配合上前述的安全内存访问指令所蕴含的操作逻辑,可以使得处于任一安全等级的内存段中程序段内的程序无法访问和修改自身程序段中的程序,从而减少了因篡改程序而产生的系统安全风险,实现了在某一个安全等级的内存段内部的保护机制。以图2为例,第一安全等级的边界地址用于分隔第一安全等级的内存段中的用户数据段与用户程序段,从而限制用户目标程序对自身进行篡改;第二安全等级的边界地址用于分隔第二安全等级的内存段中的备份数据段与重置程序段,从而限制可信安全区重置函数对自身进行篡改;第三安全等级的边界地址用于分隔第三安全等级的内存段中的密钥数据段与证明程序段,从而限制嵌套证明函数对自身进行篡改。
可选的,低安全等级的内存段的内存地址高于高安全等级的内存段,任一安全等级的合法访问范围为高于所述任一安全等级的边界地址的地址范围,所述任一安全等级的边界地址属于所述任一安全等级的内存段,所述任一安全等级的内存段中的任一安全内存访问指令在执行时用于:
将用于编译为所述任一安全内存访问指令的内存访问指令对应的原始访问地址与边界寄存器中存储的边界地址相减,并将得到的差值存储至偏移寄存器,所述边界寄存器中存储的边界地址为所述任一安全等级的边界地址;
将所述偏移寄存器中存储的所述差值取绝对值后与所述边界寄存器中存储的所述边界地址相加得到的加数作为所述任一安全内存访问指令对应的访存地址,并基于该访问地址访问内存。
本说明书实施例介绍了安全内存访问指令所具体蕴含的操作逻辑,由此我们可以分析得到本说明书实施例所涉及的编译方法的指令转换规则。以用户源程序是AT&T汇编语言为例,假设用户源程序中存在一个内存访问指令“movq%rax,0x(%rdx,%rcx,3)”,该内存访问指令所蕴含的操作逻辑为“将寄存器rax中存储的值写入地址为0x(%rdx,%rcx,3)的内存空间”,由于其对应的访问地址0x(%rdx,%rcx,3)在实际执行时是不确定的,如果直接执行该指令将带来越界访存风险。因此,为了将其限制在第一安全等级的合法访问范围内,我们可以在将其编译为作为机器码的安全内存访问指令时改变其蕴含的操作逻辑,使操作逻辑不再为直接访问地址0x(%rdx,%rcx,3),而是访问一个高于第一安全等级的边界地址的重定向地址。具体而言,如果我们对该例子中编译得到的安全内存访问指令进行反编译,可以得到如下的汇编指令集合:“
leaq 0x(%rdx,%rcx,3),%r14
subq%r15,%r14
shlq $1,%r14
shrq $1,%r14
movq%rax,(%r15,%r14,1)。”
其中,寄存器r15即存放有边界地址的边界寄存器,而寄存器r14即偏移寄存器。
因此,上述汇编指令集合所蕴含的操作逻辑也即编译得到的安全内存访问指令的操作逻辑,具体为“将地址0x(%rdx,%rcx,3)写入寄存器r14,将寄存器r14中存储的值与r15中存储的值相减得到的差值写入寄存器r14,将r14中存储的值的最高位设为0(由于最高位代表正负号,因此该操作视为取绝对值),将寄存器rax中存储的值写入地址(%r15,%r14,1),该地址为r14中存储的值与r15中存储的值之和”。不难发现,如果原始访问地址0x(%rdx,%rcx,3)高于边界地址,则最终安全内存访问指令对应的访存地址与原始访问地址一致;如果原始访问地址低于边界寄存器中的边界地址,则最终安全内存访问指令对应的访存地址被修改为一个高于边界地址的随机地址。因此,无论内存访问指令对应的原始访问地址为何,编译得到的安全内存访问指令对应的访存地址总是高于边界寄存器中的边界地址,即安全内存访问指令对应的访存地址总是属于当前的全局合法访问范围。
可选的,所述用户目标程序被设置为禁止调用所述边界寄存器与所述偏移寄存器,所述边界寄存器中存储的边界地址仅能通过执行所述系统目标程序中的边界修改函数进行修改。为了确保安全内存访问指令的有效性,我们需要确保用户目标程序无法调用所述边界寄存器与所述偏移寄存器,同时为修改边界寄存器中的边界地址提供唯一的合法渠道,从而避免通过边界修改函数以外的方式修改边界寄存器中的边界地址,确保边界寄存器中用于定义全局合法访问范围的边界地址不会被随意修改,使得安全内存访问指令能够按照预期地减少越界访存风险。
可选的,所述任一安全等级的边界地址被设置为不可访问。在处理任一安全等级的内存段中的push指令这种特殊情况时,由于执行push指令会不断降低栈指针指向的访存地址,从而可能访问到低于所述任一安全等级的边界地址的内存空间,即存在穿越所述任一安全等级的合法访问范围的风险,因此,可以强制将所述任一安全等级中边界地址设置为不可访问,从而避免因push指令所带来的越界访存风险。
可选的,所述可信安全区被划分为若干个首尾连接的内存块,同一安全内存访问指令包含于同一内存块中,所述可信安全区中的安全跳转点与任一内存块的起始地址对齐,所述可信安全区中的安全跳转点包括循环起始地址、条件分支起始地址与非敏感函数的函数起始地址;
所述可信安全区中的程序包括所述用户目标程序与由系统源程序编译得到的系统目标程序,所述系统目标程序处于第二安全等级及其以上安全等级的内存段中,所述系统目标程序包括所述可信安全区重置函数;所述用户源程序中的地址跳转指令被编译为所述用户目标程序中相应的安全地址跳转指令,和/或所述系统源程序中的地址跳转指令被编译为所述系统目标程序中相应的安全地址跳转指令,其中,任一安全地址跳转指令对应的跳转地址为用于编译为所述任一安全地址跳转指令的地址跳转指令对应的原始跳转地址所处内存块的起始地址。
如前所述,安全内存访问指令实际上是包含有一个或多个机器码的机器码集合,并且只有完整执行时才能起到规避访存越界风险的作用。然而,攻击者可以在用户目标程序或系统目标程序中利用地址跳转指令来跳过安全内存访问指令,或者通过同时修改其他寄存器的值并跳转到安全内存访问指令中间的某个机器码处,从而扰乱一次完整的安全内存访问指令的执行,甚至能够突破安全内存访问指令限制访存地址的效果,使攻击者能够越界访问到预期的合法访问范围之外的内存空间。为了避免攻击者通过地址跳转指令来部分或完全规避安全内存访问指令的有效性,本说明书实施例提出了另一种安全策略,该安全策略将可信安全区再次划分为若干个首位连接的称为内存块的地址空间,这些内存块的大小可以相同或不同,任一安全内存访问指令都被完整地包含于某一个内存块中,同时规定可信安全区中所有的安全地址跳转指令只能跳转到某一个内存块的起始地址,而不能直接跳转到任何一个内存块的内部。
通过上述安全策略,可以使得任何安全地址跳转指令总是无法跳转到某一个安全内存访问指令中间的某个机器码,这意味着攻击者无法通过自定义的地址跳转指令来扰乱任一安全内存访问指令的完整执行,从而使得任一安全内存访问指令只要被执行就必然能够达到其预期的规避访存越界风险的作用,因为源程序中的地址跳转指令总是会被编译为相应的安全地址跳转指令。当然,该安全策略无法阻止攻击者完全跳过一个安全内存访问指令,但这种情况下实际上也不会产生任何访存越界风险。
与前述的编译方法类似,本说明书实施例同样也是通过编译器技术来实现上述安全策略,在对用户源程序和/或系统源程序进行编译时,通过编译器技术来改变传统编译过程中的指令转换规则。在将用户/系统源程序编译为用户/系统目标程序的过程中,使得改变后的指令转换规则用于指导将所述用户/系统源程序中的地址跳转指令编译为所述用户/系统目标程序中相应的安全地址跳转指令,并确保用户/系统目标程序中的任一安全地址跳转指令对应的跳转地址为用于编译为所述任一安全地址跳转指令的地址跳转指令对应的原始跳转地址所处内存块的起始地址。通过本说明书实施例所涉及的编译方法,能够消除用户/系统源程序在源码层面的跳转干扰风险(跳转干扰风险是指通过跳转至安全内存访问指令内部而使安全内存访问指令失效),将具有跳转干扰风险的用户/系统源程序净化为了不具有跳转干扰风险的用户/系统目标程序。
虽然上述安全策略能够确保用户/系统目标程序不存在跳转干扰风险,然而由于客观上安全地址跳转指令相较于编译前的地址跳转指令,其所蕴含的操作逻辑已经发生了变化,使其无法正常跳转到地址跳转指令对应的原始跳转地址,而是会被引导跳转至原始跳转地址所处内存块的起始地址,这将有可能导致用户/系统目标程序无法完成其正常执行流程。为避免上述安全策略影响用户/系统目标程序的正常执行流程,我们还将所述可信安全区中的安全跳转点与任一内存块的起始地址对齐,所述可信安全区中的安全跳转点包括循环起始地址、条件分支起始地址与非敏感函数的函数起始地址,具体而言,是在将编译得到的用户/系统目标程序加载至可信安全区中时,将用户/系统目标程序中包含的安全跳转点与事先划分好的内存块的起始地址自动对齐。可信安全区中的安全跳转点是指为了使得用户/系统目标程序能够正常执行而必需的一些跳转点,例如对于一个循环逻辑而言,其必然会存在一个被反复跳转的循环起始地址,又例如对于一个条件分支逻辑而言,在不同的条件下会跳转至不同的条件分支起始地址,再例如如果需要通过跳转方式调用一个非敏感函数,则必然需要跳转至该非敏感函数的函数起始地址。由于可信安全区中的所有安全跳转点均与可信安全区中相应内存块的起始地址对齐,因此如果要维持用户/系统目标程序的正常执行流程,只需要利用仅能跳转至某一个内存块的起始地址的安全地址跳转指令就可以实现,即在这种安全跳转点与内存块起始地址的对齐设计下,可以在消除用户/系统源程序在源码层面的跳转干扰风险的同时,不影响用户/系统目标程序的正常执行。
另外,为了避免安全地址跳转指令直接跳转到敏感函数或敏感指令处执行,还可以设置任一内存块的起始地址不与敏感指令或敏感函数的起始地址对齐。本说明书实施例所涉及的敏感指令是指可能会对可信安全区的安全性造成破坏的指令,例如前述的用户权限硬件指令,本说明书实施例涉及的敏感函数是指可能会对可信安全区的安全性造成破坏的函数,例如前述的边界修改函数。
图3是一示例性实施例提供的一种划分内存块后的可信安全区的示意图。如图3所示,如果用户/系统源程序中的地址跳转指令所蕴含的操作逻辑是跳转至内存块a中间的某个地址的话,那么将该地址跳转指令通过本说明书涉及的编译方法进行编译得到的安全地址跳转指令则在执行时用于:跳转至内存块a的起始地址(图中内存块a的安全跳转点)。
可选的,所述任一安全地址跳转指令在执行时用于:
将用于编译为所述任一安全地址跳转指令的地址跳转指令对应的原始跳转地址与对齐常量进行与运算,并将与运算得到的结果作为跳转地址进行跳转。
本说明书实施例介绍了安全地址跳转指令所具体蕴含的操作逻辑,由此我们可以分析得到本说明书实施例所涉及的编译方法的指令转换规则。以用户源程序是AT&T汇编语言为例,假设用户源程序中存在一个地址跳转指令“jmpq*%rax”,该地址跳转指令所蕴含的操作逻辑为“将寄存器rax存储的值作为跳转地址进行跳转”,由于其对应的跳转地址*%rax在实际执行时是不确定的,如果直接执行该指令将带来跳转干扰风险。因此,为了确保不会跳转至安全地址跳转指令中间的机器码,我们可以在将其编译为作为机器码的安全地址跳转指令时改变其蕴含的操作逻辑,使操作逻辑不再为直接跳转至地址*%rax,而是跳转至与地址*%rax邻近的一个内存块的起始地址。具体而言,如果我们对该例子中编译得到的安全地址跳转指令进行反编译,可以得到如下的汇编指令集合:“
andq%rax,0Xffffffffffffffe0
jmpq *%rax。”
其中,0Xffffffffffffffe0为对齐常量,每个内存块的起始地址的后五位均为0,因此每个内存块的地址空间均为固定的32bit(每个内存块最多容纳32条指令)。
因此,上述汇编指令集合所蕴含的操作逻辑也即编译得到的安全地址跳转指令的操作逻辑,具体为“将寄存器rax存储的值与对齐常量0Xffffffffffffffe0进行与运算得到的某一个内存块的起始地址存放至寄存器rax,将寄存器rax存储的值作为跳转地址进行跳转”。不难发现,如果原始跳转地址为某一个的内存块的起始地址(由于采用了安全跳转点与内存块起始地址的对齐设计,因此其在正常执行流程下必然为某一个的内存块的起始地址),则最终安全地址跳转指令对应的跳转地址与原始跳转地址一致;如果原始跳转地址不为某一个的内存块的起始地址(通常意味着程序作恶),则最终安全地址跳转指令对应的跳转地址被修改为原始跳转地址所处内存块的起始地址。因此,无论地址跳转指令对应的原始跳转地址为何,编译得到的安全地址跳转指令对应的跳转地址总是被吸附至某一个内存块的起始地址。
另外,作为用户/系统源程序中的地址跳转指令的ret指令也需要进行类似的编译过程,将地址跳转指令编译为用户/系统目标程序中的安全地址跳转指令以消除对应的跳转干扰风险。ret指令通常是用于在被调用函数执行完毕后跳转至调用点处,通常情况下调用点的地址会存放至栈顶,然而如果攻击者在被调用函数的执行过程中修改栈顶存放的值,则可能使得ret指令返回至任意内存地址,带来跳转干扰风险。
假设用户源程序中存在一个地址跳转指令“retq”,该地址跳转指令所蕴含的操作逻辑为“将栈顶存放的值作为跳转地址进行跳转”,由于其对应的跳转地址在实际执行时是不确定的,如果直接执行该指令将带来跳转干扰风险。因此,为了确保不会跳转至安全地址跳转指令中间的机器码,我们可以在将其编译为作为机器码的安全地址跳转指令时改变其蕴含的操作逻辑,使操作逻辑不再为直接跳转至作为原始跳转地址的栈顶存放的值,而是跳转至与原始跳转地址邻近的一个内存块的起始地址。具体而言,如果我们对该例子中编译得到的安全地址跳转指令进行反编译,可以得到如下的汇编指令集合:“
popq%r14
andq%r14,0Xffffffffffffffe0
jmpq *%r14。”
其中,寄存器r14作为偏移寄存器除了存放前述的差值,还在这里用于存放跳转地址(由于指令必然是由CPU串行执行的,因此作为CPU寄存器的r14可以在不同的指令中复用),0Xffffffffffffffe0为对齐常量,每个内存块的起始地址的后五位均为0,因此每个内存块的地址空间均为固定的32bit。
因此,上述汇编指令集合所蕴含的操作逻辑也即编译得到的安全地址跳转指令的操作逻辑,具体为“将栈顶存放的值出栈并存放至寄存器rax,将寄存器rax存储的值与对齐常量0Xffffffffffffffe0进行与运算得到的某一个内存块的起始地址存放至寄存器rax,将寄存器rax存储的值作为跳转地址进行跳转”。与前述的记载类似,无论地址跳转指令对应的原始跳转地址为何,编译得到的安全地址跳转指令对应的跳转地址总是被吸附至某一个内存块的起始地址。
可选的,所述系统目标程序中的任一敏感函数在其占用的内存块中的函数起始地址与该内存块的起始地址之间插入有停机指令,所述停机指令在执行时用于触发系统停机。在本说明书实施例中,为了避免通过前述的安全地址跳转指令跳转至敏感函数从而破坏系统的安全性,可以设置任一敏感函数与其所处的内存块不对齐。具体而言,可以在任一敏感函数占用的内存块中的函数起始地址与该内存块的起始地址之间插入有停机指令,使存放有敏感函数的内存块的起始地址与停机指令对齐,这样一来,即使安全地址跳转指令跳转到了存放有敏感函数的内存块,也会被首先引导至停机指令从而触发系统停机,确保敏感函数无法通过安全跳转指令进行跳转执行,维护了系统的安全性。如图3所示,由于内存块b和内存块c均需要存放敏感函数a,因此内存块b和内存块c的起始地址均与停机指令对齐,而不会与敏感函数a对齐,这确保了通过安全地址跳转指令在跳转至内存块b和内存块c时,只能跳转到其上的停机指令,从而保护了敏感函数a不会被随意跳转调用。需要注意的是,停机指令可以看作一种非敏感函数,因此其也视为一类安全跳转点。
可选的,在所述任一敏感函数占用有至少两个内存块的情况下,所述至少两个内存块中的所述任一敏感函数通过标签跳转指令进行连接。
在本说明书实施例中,跳转指令按照类型可以分为地址跳转指令与标签跳转指令,其中,地址跳转指令就是按照指令中给出的跳转地址进行跳转的指令,例如“jmpq *%rax”就是指跳转至寄存器rax中存储的地址所在的内存空间;而标签跳转指令则是按照指令中给出的标签进行直接跳转的指令,例如“jmp L1”就是指跳转至全局唯一的标签L1处所标记的内存空间。在本说明书实施例中,地址跳转指令会按照前述改变后的指令转换规则编译为安全跳转指令,而标签跳转指令则会按照传统编译过程中的指令转换规则进行编译,因此其蕴含的操作逻辑不会产生变化。
在本说明书实施例中,同一敏感函数其可能包含大量的指令,因此可能无法被完整存放进同一个内存块中,而在同一敏感函数占用至少两个内存块的情况下,由于指令运行时是顺序执行的,两个内存块的交界处必然会被停机指令所隔断,这导致敏感函数无法正常进行执行。基于此,我们将存储于不同内存块中的同一敏感函数通过标签跳转指令连接起来,从而可以使得敏感函数的大小多大,都可以正常执行而不会被停机指令所中断。如图3所示,敏感函数a需要同时占用内存块b和内存块c,然而内存块c开头的停机指令会阻断敏感函数a的正常执行,于是我们通过在内存块b中存储的敏感函数a的第一部分的末尾添加一个标签跳转指令,同时将该标签跳转指令所跳转的标签标记为内存块c中存储的敏感函数a的第二部分的起始地址处,从而使得敏感函数a在执行完第一部分后通过标签跳转指令跳转至第二部分继续执行,而不会影响敏感函数a的正常执行流程。
可选的,任一内存块的起始地址与相应的安全检测函数的函数起始地址对齐,任一内存块中的安全检测函数在执行时用于:
确定跳转至所述任一内存块中的安全检测函数的安全地址跳转指令所处的跳转点内存段的安全等级;
在确定用于编译为该安全地址跳转指令的地址跳转指令对应的原始跳转地址或所述任一内存块的起始地址不属于所述跳转点内存段的安全等级的合法访问范围的情况下,触发系统停机;
在确定该原始跳转地址或所述任一内存块的起始地址属于所述跳转点内存段的安全等级的合法访问范围的情况下,顺序执行下一个指令或跳转至该原始跳转地址。
本说明书实施例所涉及的安全检测函数属于系统目标函数中的非敏感函数,由于其会被插入至每个内存块的开头而用户程序段中可能包括一个或多个内存块,因此用户程序段中也会被插入一个或多个安全检测函数,而该插入的过程发生在将用户目标程序加载至用户程序段的过程中,使得用户程序段中同时混杂有用户目标程序与系统目标程序。安全检测函数可以通过边界寄存器中的值来确定跳转至所述任一内存块中的安全检测函数的安全地址跳转指令所处的跳转点内存段的安全等级,具体而言,可以将边界寄存器中的值与不同安全等级的边界地址进行比对,从而将比对一致的边界地址的安全等级确定为跳转点内存段的安全等级。为了使安全检测函数能够获取用于编译为跳转至此处的安全地址跳转指令的地址跳转指令对应的原始跳转地址,可以在将地址跳转指令编译为安全地址跳转指令时添加一个操作逻辑,使得安全地址跳转指令中还包括如下操作逻辑:在进行与运算之前将原始跳转地址入栈从而将原始跳转地址到保留在堆栈中。而在安全检测函数执行的过程中,就可以通过出栈指令来获取该原始跳转指令。我们还可以设置任一安全等级的合法访问范围的边界与内存块的边界对齐,这意味着任何一个内存块都不会跨越不同安全等级的合法访问范围,因此只要跳转到任一内存块的起始地址没有越界就能够说明跳转到该任一内存块中的任意地址都不会越界。于是,如果在确定原始跳转地址或所述任一内存块的起始地址(所述任一内存块的起始地址维护于所述任一内存块中的安全检测函数之内而不需要从其他地方获取)属于所述跳转点内存段(即跳转至所述任一内存块中的安全检测函数的安全地址跳转指令所处的内存段)的安全等级的合法访问范围的情况下,则说明该跳转合法,便可以进行顺序执行下一个指令或跳转至原始跳转地址继续执行;否则证明该跳转不合法,将执行一个停机指令并触发系统停机。本说明书实施例可以彻底清除系统中因地址跳转指令而带来的越界跳转风险,使得任何程序不仅无法访问其合法访问范围之外的内存地址,也无法正常跳转至其合法访问范围之外的内存地址。
另外,为了确保各用户/系统目标程序的正常执行而不会被内存块中插入的安全检测函数所打断,可以在连续的内存块之间通过标签跳转指令进行连接从而在用户/系统目标程序正常的顺序执行时跳过执行安全监测函数,例如在每个内存块的末尾插入一个标签跳转指令,该标签跳转指令所跳转的标签标记为下一个内存块中安全检测函数的函数终止地址后的地址。
在本说明书实施例中,所述用户目标程序由所述可信安全区中的解释器将所述用户源程序编译得到;或者,所述用户目标程序由可信编译平台将所述用户源程序通过运行前编译得到,所述方法还包括:
获取所述用户目标程序,在确定所述可信编译平台提供的所述用户目标程序对应的签名验签成功的情况下,将所述用户目标程序加载至所述用户程序段。
可信安全区中内嵌有解释器以实现将用户/系统源程序编译为用户/系统目标程序的功能,这种情况下可信安全区可以确定编译得到的用户目标程序由于使用了本说明书实施例所涉及的编译方法,于是不需要进一步确定用户目标程序是否可信。然而,如果是在AOT(Ahead-of-time,运行前编译)的场景下,可信安全区所直接接收到的就是用户目标程序,由于无法确定该用户目标程序是否使用了本说明书实施例所涉及的编译方法,因此还需要对其可信度进行验证后才会能将其加载至用户程序段,从而确保加载至用户程序段中的用户目标程序的访存越界风险、跳转干扰风险等风险已经消除。
可信安全区可以自己对所述可信编译平台提供的所述用户目标程序对应的签名进行验签,也可以由其他可信安全区所信任的可信机构对所述可信编译平台提供的所述用户目标程序对应的签名进行验签,然后基于对该可信机构的信任,可信安全区可以在确认该可信机构对签名验证成功的情况下将所述用户目标程序加载至所述用户程序段。图8是一示例性实施例提供的一种可信计算系统的系统架构图,以图8为例,假设后端可信安全区需要加载一个由外部可信编译平台所编译得到的用户目标程序,那么该用户目标程序对应的签名可以由后端可信安全区自身进行验签,也可以交由前端可信安全区进行验签,然后在前端可信安全区验签成功的情况下通知后端可信安全区,后端可信安全区基于与前端可信安全区之间的信任关系从而可以将所述用户目标程序加载至所述用户程序段。
请参见图4,图4是一示例性实施例提供的一种编译方法的流程图。如图1所示,该方法包括:
S402:获取用于在可信安全区中执行的用户源程序,所述可信安全区包括第一安全等级的内存段与第二安全等级的内存段,其中,第一安全等级的内存段包括用户数据段与用户程序段,第二安全等级的内存段包括备份数据段与重置程序段,第一安全等级的合法访问范围包括第一安全等级的内存段中的至少一部分内存地址,所述用户程序段中的安全内存访问指令对应的访存地址属于第一安全等级的合法访问范围。
S404:将所述用户源程序编译为用户目标程序,以使得所述用户源程序中的内存访问指令转换为所述用户目标程序中相应的安全内存访问指令。
S406:将所述用户目标程序加载至所述用户程序段,以由所述可信安全区响应于任务请求进行重置后执行所述用户程序段中的所述用户目标程序;其中,对所述可信安全区进行重置包括:执行所述重置程序段中的可信安全区重置函数,将所述备份数据段中存储的内存备份覆盖至第一安全等级的合法访问范围对应的内存空间,所述内存备份包括用于覆盖至所述用户数据段的用户数据段备份。
本说明书实施例所涉及的编译方法在前文实施例中已经有详细的记载,这里不再赘述。需要注意的是,本说明书实施例所涉及的编译方法同样适用于将系统源程序编译为系统目标程序。
通过本说明书实施例涉及的编译方法,配合划分有不同安全等级的内存段的可信安全区的内存架构,能够使得用户源程序中的内存访问指令转换为用户目标程序中相应的安全内存访问指令,且安全内存访问指令对应的访存地址属于第一安全等级的合法访问范围,由此一来就将具有跳转干扰风险的用户源程序净化为了不具有跳转干扰风险的用户目标程序。同时,在基于上述编译方法编译得到用户目标程序并加载至可信安全区中后,辅以不同安全等级的内存段的设计,能够实现一种可信安全区的安全重置方法,相较于传统的热启动,本说明书实施例所涉及的安全重置方法实现了只有传统的冷启动才能实现的消除安全隐患的效果,从而兼顾了安全性与效率。
图5是一示例性实施例提供的一种设备的示意结构图。请参考图5,在硬件层面,该设备包括处理器502、内部总线504、网络接口506、内存508以及非易失性存储器510,当然还可能包括其他业务所需要的硬件。本说明书一个或多个实施例可以基于软件方式来实现,比如由处理器502从非易失性存储器510中读取对应的计算机程序到内存508中然后运行。当然,除了软件实现方式之外,本说明书一个或多个实施例并不排除其他实现方式,比如逻辑器件抑或软硬件结合的方式等等,也就是说以下处理流程的执行主体并不限定于各个逻辑单元,也可以是硬件或逻辑器件。
如图6所示,图6是本说明书根据一示例性实施例提供的一种基于可信安全区的请求处理装置的框图,该装置可以应用于如图5所示的设备中,以实现本说明书的技术方案。所述可信安全区包括第一安全等级的内存段与第二安全等级的内存段,其中,第一安全等级的内存段包括用户数据段与用户程序段,第二安全等级的内存段包括备份数据段与重置程序段,第一安全等级的合法访问范围包括第一安全等级的内存段中的至少一部分内存地址;所述装置包括:
重置单元601,用于响应于任务请求,执行所述重置程序段中的可信安全区重置函数,将所述备份数据段中存储的内存备份覆盖至第一安全等级的合法访问范围对应的内存空间,所述内存备份包括用于覆盖至所述用户数据段的用户数据段备份;
用户目标程序执行单元602,用于在所述可信安全区重置函数执行完成后,执行所述用户程序段中由用户源程序编译得到的用户目标程序;其中,所述用户源程序中的内存访问指令被编译为所述用户目标程序中相应的安全内存访问指令,所述安全内存访问指令对应的访存地址属于第一安全等级的合法访问范围。
可选的,所述重置单元601具体用于:
启用用户权限硬件指令,并通过所述用户权限硬件指令为第一安全等级的合法访问范围对应的内存空间重新分配内存访问权限;
将所述备份数据段中存储的内存备份覆盖至第一安全等级的合法访问范围对应的内存空间,并在完成后禁用所述用户权限硬件指令。
可选的,所述内存备份还包括用于覆盖至所述用户程序段的用户程序段备份。
可选的,还包括:
执行结果返回单元603,用于响应于所述任务请求,将执行所述用户目标程序所生成的所述任务请求对应的执行结果返回至所述任务请求的发起方。
可选的,还包括:
备份单元604,用于响应于备份请求或者在所述可信安全区完成冷启动的情况下,执行所述重置程序段中的可信安全区备份函数,将第一安全等级的合法访问范围中的数据作为所述内存备份存储至所述备份数据段。
可选的,所述可信安全区被划分为若干个首尾连接的内存块,同一安全内存访问指令包含于同一内存块中,所述可信安全区中的安全跳转点与任一内存块的起始地址对齐,所述可信安全区中的安全跳转点包括循环起始地址、条件分支起始地址与非敏感函数的函数起始地址;
所述可信安全区中的程序包括所述用户目标程序与由系统源程序编译得到的系统目标程序,所述系统目标程序处于第二安全等级及其以上安全等级的内存段中,所述系统目标程序包括所述可信安全区重置函数;所述用户源程序中的地址跳转指令被编译为所述用户目标程序中相应的安全地址跳转指令,和/或所述系统源程序中的地址跳转指令被编译为所述系统目标程序中相应的安全地址跳转指令,其中,任一安全地址跳转指令对应的跳转地址为用于编译为所述任一安全地址跳转指令的地址跳转指令对应的原始跳转地址所处内存块的起始地址。
可选的,所述系统目标程序中的任一敏感函数在其占用的内存块中的函数起始地址与该内存块的起始地址之间插入有停机指令,所述停机指令在执行时用于触发系统停机。
可选的,在所述任一敏感函数占用有至少两个内存块的情况下,所述至少两个内存块中的所述任一敏感函数通过标签跳转指令进行连接。
可选的,任一内存块的起始地址与相应的安全检测函数的函数起始地址对齐,任一内存块中的安全检测函数在执行时用于:
确定跳转至所述任一内存块中的安全检测函数的安全地址跳转指令所处的跳转点内存段的安全等级;
在确定用于编译为该安全地址跳转指令的地址跳转指令对应的原始跳转地址或所述任一内存块的起始地址不属于所述跳转点内存段的安全等级的合法访问范围的情况下,触发系统停机;
在确定该原始跳转地址或所述任一内存块的起始地址属于所述跳转点内存段的安全等级的合法访问范围的情况下,顺序执行下一个指令或跳转至该原始跳转地址。
可选的,所述可信安全区还包括第三安全等级的内存段,第三安全等级的内存段包括密钥数据段与证明程序段,所述装置还包括:
嵌套证明单元605,用于响应于程序证明请求,执行所述证明程序段中的嵌套证明函数,基于所述密钥数据段中存储的嵌套证明私钥对待证明数据进行签名以生成可信程序证明,所述待证明数据包括所述用户程序段和/或重置程序段中的数据;
将所述可信程序证明提供至所述程序证明请求的发起方,并接收在所述发起方确认所述可信程序证明验证通过的情况下发送的所述任务请求。
可选的,所述嵌套证明私钥由密钥管理服务器在确认所述可信安全区通过远程认证服务器的远程认证的情况下分配至所述可信安全区中的所述密钥数据段。
可选的,所述可信安全区包括不同安全等级的内存段,所述不同安全等级至少包括第一安全等级与第二安全等级,其中,任一安全等级的合法访问范围包括所述任一安全等级的内存段中的至少一部分内存地址以及低于所述任一安全等级的内存段;
所述可信安全区中的程序包括所述用户目标程序与由系统源程序编译得到的系统目标程序,所述系统目标程序处于第二安全等级及其以上安全等级的内存段中,所述系统目标程序包括所述可信安全区重置函数;所述系统源程序中的内存访问指令被编译为所述系统目标程序中相应的安全内存访问指令,其中,所述任一安全等级的内存段中的安全内存访问指令对应的访存地址属于所述任一安全等级的合法访问范围。
可选的,低安全等级的内存段的内存地址高于高安全等级的内存段,任一安全等级的合法访问范围为高于所述任一安全等级的边界地址的地址范围,所述任一安全等级的边界地址属于所述任一安全等级的内存段,所述任一安全等级的内存段中的任一安全内存访问指令在执行时用于:
将用于编译为所述任一安全内存访问指令的内存访问指令对应的原始访问地址与边界寄存器中存储的边界地址相减,并将得到的差值存储至偏移寄存器,所述边界寄存器中存储的边界地址为所述任一安全等级的边界地址;
将所述偏移寄存器中存储的所述差值取绝对值后与所述边界寄存器中存储的所述边界地址相加得到的加数作为所述任一安全内存访问指令对应的访存地址,并基于该访问地址访问内存。
可选的,所述用户目标程序被设置为禁止调用所述边界寄存器与所述偏移寄存器,所述边界寄存器中存储的边界地址仅能通过执行所述系统目标程序中的边界修改函数进行修改。
可选的,所述可信安全区定义有全局合法访问范围,所述全局合法访问范围在通过合法调用逻辑跳转至所述任一安全等级的内存段时被设置为所述任一安全等级的合法访问范围,否则被设置为第一安全等级的合法访问范围;所述任一安全等级的内存段中的安全内存访问指令对应的访存地址属于所述全局合法访问范围。
可选的,低安全等级的内存段的内存地址高于高安全等级的内存段,任一安全等级的合法访问范围为高于所述任一安全等级的边界地址的地址范围,所述任一安全等级的边界地址属于所述任一安全等级的内存段,所述全局合法访问范围为高于边界寄存器中存储的边界地址,所述合法调用逻辑包括通过所述系统目标程序中的边界修改函数实现的调用逻辑;
执行属于所述系统目标程序且处于所述任一安全等级的内存段中的任一系统函数,包括:
调用所述边界修改函数,将所述边界寄存器中存储的原边界地址修改为所述任一安全等级的边界地址;
在所述边界修改函数中调用执行所述任一系统函数,并在执行完成所述任一系统函数后,将边界寄存器中存储的边界地址修改为所述原边界地址。
可选的,所述任一安全等级的内存段包括相应的数据段与内存地址低于该数据段的程序段,所述任一安全等级的边界地址用于分隔所述任一安全等级的内存段中的数据段与程序段。
可选的,所述任一安全等级的边界地址被设置为不可访问。
可选的,所述用户目标程序由所述可信安全区中的解释器将所述用户源程序编译得到;或者,
所述用户目标程序由可信编译平台将所述用户源程序通过运行前编译得到,所述装置还包括:
验签单元606,用于获取所述用户目标程序,在确定所述可信编译平台提供的所述用户目标程序对应的签名验签成功的情况下,将所述用户目标程序加载至所述用户程序段。
如图7所示,图7是本说明书根据一示例性实施例提供的一种编译装置的框图,该装置可以应用于如图5所示的设备中,以实现本说明书的技术方案。所述装置包括:
用户源程序获取单元701,获取用于在可信安全区中执行的用户源程序,所述可信安全区包括第一安全等级的内存段与第二安全等级的内存段,其中,第一安全等级的内存段包括用户数据段与用户程序段,第二安全等级的内存段包括备份数据段与重置程序段,第一安全等级的合法访问范围包括第一安全等级的内存段中的至少一部分内存地址,所述用户程序段中的安全内存访问指令对应的访存地址属于第一安全等级的合法访问范围;
编译单元702,用于将所述用户源程序编译为用户目标程序,以使得所述用户源程序中的内存访问指令转换为所述用户目标程序中相应的安全内存访问指令;
用户目标程序加载单元703,用于将所述用户目标程序加载至所述用户程序段,以由所述可信安全区响应于任务请求进行重置后执行所述用户程序段中的所述用户目标程序;其中,对所述可信安全区进行重置包括:执行所述重置程序段中的可信安全区重置函数,将所述备份数据段中存储的内存备份覆盖至第一安全等级的合法访问范围对应的内存空间,所述内存备份包括用于覆盖至所述用户数据段的用户数据段备份。
上述装置实施例与前述方法实施例相对应,不存在本质上的差异,前文针对图1与图4所示实施例的描述,均适用于图6与图7所示的实施例,这里不再赘述。
如图8所示,图8是本说明书根据一示例性实施例提供的一种可信计算系统的系统架构图。所述可信计算系统包括一个前端可信安全区与至少一个后端可信安全区,其中:
所述前端可信安全区用于接收客户端发送的任务请求,并将该任务请求转发至对应的后端可信安全区,以及将该后端可信安全区返回的针对该任务请求的执行结果发送至所述客户端;
任一后端可信安全区用于在接收到所述前端可信安全区发送的任务请求的情况下执行如前述任一基于可信安全区的请求处理方法,并将执行用户目标程序所生成的执行结果返回至所述前端可信安全区。
如图8所示,可选计算系统中的前端可信安全区不需要承担执行可信计算任务的职能,而只作为客户端与后端可信安全区之间的中转站,真正执行可信计算任务的职能则由多个后端可信安全区承担。作为可信计算系统外部的客户端只与前端可信安全区建立信任关系并进行对接,而无需直接与多个用于执行不同可信计算任务的后端可信安全区建立信任关系,因此提高了客户端的便利性;同时,多个后端可信安全区只需要与前端可信安全区建立信任关系并对接,而无需直接面向不同的客户端与不同的客户端分别建立信任关系,因此在系统层面大大减小了网络连接和信任关系的维护成本。
本说明书实施例所涉及的可信计算系统中的后端可信安全区在处理任务请求时,通过前述的基于可信安全区的请求处理方法完成了快速且安全地重启过程,进而能够快速响应并执行任务请求对应的可信计算任务,同时,后端可信安全区采用的按照安全等级分段的安全策略也能够确保用于执行可信计算任务的用户目标程序难以从内部破坏可信安全区的安全性。
本说明书实施例中涉及后端可信安全区处理任务请求的过程可以参见前文实施例的描述,这里不再赘述。
在20世纪90年代,对于一个技术的改进可以很明显地区分是硬件上的改进(例如,对二极管、晶体管、开关等电路结构的改进)还是软件上的改进(对于方法流程的改进)。然而,随着技术的发展,当今的很多方法流程的改进已经可以视为硬件电路结构的直接改进。设计人员几乎都通过将改进的方法流程编程到硬件电路中来得到相应的硬件电路结构。因此,不能说一个方法流程的改进就不能用硬件实体模块来实现。例如,可编程逻辑器件(Programmable Logic Device, PLD)(例如现场可编程门阵列(Field Programmable GateArray,FPGA))就是这样一种集成电路,其逻辑功能由用户对器件编程来确定。由设计人员自行编程来把一个数字系统“集成”在一片PLD上,而不需要请芯片制造厂商来设计和制作专用的集成电路芯片。而且,如今,取代手工地制作集成电路芯片,这种编程也多半改用“逻辑编译器(logic compiler)”软件来实现,它与程序开发撰写时所用的软件编译器相类似,而要编译之前的原始代码也得用特定的编程语言来撰写,此称之为硬件描述语言(Hardware Description Language,HDL),而HDL也并非仅有一种,而是有许多种,如ABEL(Advanced Boolean Expression Language)、AHDL(Altera Hardware DescriptionLanguage)、Confluence、CUPL(Cornell University Programming Language)、HDCal、JHDL(Java Hardware Description Language)、Lava、Lola、MyHDL、PALASM、RHDL(RubyHardware Description Language)等,目前最普遍使用的是VHDL(Very-High-SpeedIntegrated Circuit Hardware Description Language)与Verilog。本领域技术人员也应该清楚,只需要将方法流程用上述几种硬件描述语言稍作逻辑编程并编程到集成电路中,就可以很容易得到实现该逻辑方法流程的硬件电路。
控制器可以按任何适当的方式实现,例如,控制器可以采取例如微处理器或处理器以及存储可由该(微)处理器执行的计算机可读程序代码(例如软件或固件)的计算机可读介质、逻辑门、开关、专用集成电路(Application Specific Integrated Circuit,ASIC)、可编程逻辑控制器和嵌入微控制器的形式,控制器的例子包括但不限于以下微控制器:ARC 625D、Atmel AT91SAM、Microchip PIC18F26K20 以及Silicone Labs C8051F320,存储器控制器还可以被实现为存储器的控制逻辑的一部分。本领域技术人员也知道,除了以纯计算机可读程序代码方式实现控制器以外,完全可以通过将方法步骤进行逻辑编程来使得控制器以逻辑门、开关、专用集成电路、可编程逻辑控制器和嵌入微控制器等的形式来实现相同功能。因此这种控制器可以被认为是一种硬件部件,而对其内包括的用于实现各种功能的装置也可以视为硬件部件内的结构。或者甚至,可以将用于实现各种功能的装置视为既可以是实现方法的软件模块又可以是硬件部件内的结构。
上述实施例阐明的系统、装置、模块或单元,具体可以由计算机芯片或实体实现,或者由具有某种功能的产品来实现。一种典型的实现设备为服务器系统。当然,本发明不排除随着未来计算机技术的发展,实现上述实施例功能的计算机例如可以为个人计算机、膝上型计算机、车载人机交互设备、蜂窝电话、相机电话、智能电话、个人数字助理、媒体播放器、导航设备、电子邮件设备、游戏控制台、平板计算机、可穿戴设备或者这些设备中的任何设备的组合。
虽然本说明书一个或多个实施例提供了如实施例或流程图所述的方法操作步骤,但基于常规或者无创造性的手段可以包括更多或者更少的操作步骤。实施例中列举的步骤顺序仅仅为众多步骤执行顺序中的一种方式,不代表唯一的执行顺序。在实际中的装置或终端产品执行时,可以按照实施例或者附图所示的方法顺序执行或者并行执行(例如并行处理器或者多线程处理的环境,甚至为分布式数据处理环境)。术语“包括”、“包含”或者其任何其他变体意在涵盖非排他性的包含,从而使得包括一系列要素的过程、方法、产品或者设备不仅包括那些要素,而且还包括没有明确列出的其他要素,或者是还包括为这种过程、方法、产品或者设备所固有的要素。在没有更多限制的情况下,并不排除在包括所述要素的过程、方法、产品或者设备中还存在另外的相同或等同要素。例如若使用到第一,第二等词语用来表示名称,而并不表示任何特定的顺序。
为了描述的方便,描述以上装置时以功能分为各种模块分别描述。当然,在实施本说明书一个或多个时可以把各模块的功能在同一个或多个软件和/或硬件中实现,也可以将实现同一功能的模块由多个子模块或子单元的组合实现等。以上所描述的装置实施例仅仅是示意性的,例如,所述单元的划分,仅仅为一种逻辑功能划分,实际实现时可以有另外的划分方式,例如多个单元或组件可以结合或者可以集成到另一个系统,或一些特征可以忽略,或不执行。另一点,所显示或讨论的相互之间的耦合或直接耦合或通信连接可以是通过一些接口,装置或单元的间接耦合或通信连接,可以是电性,机械或其它的形式。
本发明是参照根据本发明实施例的方法、装置(系统)、和计算机程序产品的流程图和/或方框图来描述的。应理解可由计算机程序指令实现流程图和/或方框图中的每一流程和/或方框、以及流程图和/或方框图中的流程和/或方框的结合。可提供这些计算机程序指令到通用计算机、专用计算机、嵌入式处理机或其他可编程数据处理设备的处理器以产生一个机器,使得通过计算机或其他可编程数据处理设备的处理器执行的指令产生用于实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能的装置。
这些计算机程序指令也可存储在能引导计算机或其他可编程数据处理设备以特定方式工作的计算机可读存储器中,使得存储在该计算机可读存储器中的指令产生包括指令装置的制造品,该指令装置实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能。
这些计算机程序指令也可装载到计算机或其他可编程数据处理设备上,使得在计算机或其他可编程设备上执行一系列操作步骤以产生计算机实现的处理,从而在计算机或其他可编程设备上执行的指令提供用于实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能的步骤。
在一个典型的配置中,计算设备包括一个或多个处理器(CPU)、输入/输出接口、网络接口和内存。
内存可能包括计算机可读介质中的非永久性存储器,随机存取存储器(RAM)和/或非易失性内存等形式,如只读存储器(ROM)或闪存(flash RAM)。内存是计算机可读介质的示例。
计算机可读介质包括永久性和非永久性、可移动和非可移动媒体可以由任何方法或技术来实现信息存储。信息可以是计算机可读指令、数据结构、程序的模块或其他数据。计算机的存储介质的例子包括,但不限于相变内存(PRAM)、静态随机存取存储器(SRAM)、动态随机存取存储器(DRAM)、其他类型的随机存取存储器(RAM)、只读存储器(ROM)、电可擦除可编程只读存储器(EEPROM)、快闪记忆体或其他内存技术、只读光盘只读存储器(CD-ROM)、数字多功能光盘(DVD)或其他光学存储、磁盒式磁带,磁带磁磁盘存储、石墨烯存储或其他磁性存储设备或任何其他非传输介质,可用于存储可以被计算设备访问的信息。按照本文中的界定,计算机可读介质不包括暂存电脑可读媒体(transitory media),如调制的数据信号和载波。
本领域技术人员应明白,本说明书一个或多个实施例可提供为方法、系统或计算机程序产品。因此,本说明书一个或多个实施例可采用完全硬件实施例、完全软件实施例或结合软件和硬件方面的实施例的形式。而且,本说明书一个或多个实施例可采用在一个或多个其中包含有计算机可用程序代码的计算机可用存储介质(包括但不限于磁盘存储器、CD-ROM、光学存储器等)上实施的计算机程序产品的形式。
本说明书一个或多个实施例可以在由计算机执行的计算机可执行指令的一般上下文中描述,例如程序模块。一般地,程序模块包括执行特定任务或实现特定抽象数据类型的例程、程序、对象、组件、数据结构等等。也可以在分布式计算环境中实践本本说明书一个或多个实施例,在这些分布式计算环境中,由通过通信网络而被连接的远程处理设备来执行任务。在分布式计算环境中,程序模块可以位于包括存储设备在内的本地和远程计算机存储介质中。
本说明书中的各个实施例均采用递进的方式描述,各个实施例之间相同相似的部分互相参见即可,每个实施例重点说明的都是与其他实施例的不同之处。尤其,对于系统实施例而言,由于其基本相似于方法实施例,所以描述的比较简单,相关之处参见方法实施例的部分说明即可。在本说明书的描述中,参考术语“一个实施例”、“一些实施例”、“示例”、“具体示例”、或“一些示例”等的描述意指结合该实施例或示例描述的具体特征、结构、材料或者特点包含于本说明书的至少一个实施例或示例中。在本说明书中,对上述术语的示意性表述不必须针对的是相同的实施例或示例。而且,描述的具体特征、结构、材料或者特点可以在任一个或多个实施例或示例中以合适的方式结合。此外,在不相互矛盾的情况下,本领域的技术人员可以将本说明书中描述的不同实施例或示例以及不同实施例或示例的特征进行结合和组合。
以上所述仅为本说明书一个或多个实施例的实施例而已,并不用于限制本本说明书一个或多个实施例。对于本领域技术人员来说,本说明书一个或多个实施例可以有各种更改和变化。凡在本说明书的精神和原理之内所作的任何修改、等同替换、改进等,均应包含在权利要求范围之内。