适用于功能和信息安全芯片的CPU指令保护方法及系统
技术领域
本发明涉及芯片安全技术领域,具体而言涉及一种适用于功能和信息安全芯片的CPU指令保护方法及系统。
背景技术
CPU(central processing unit,中央处理器)是计算机系统的运算和控制核心,CPU指令就是指挥机器工作的指示和命令,程序就是一系列按一定顺序排列的指令,执行程序的过程就是计算机的工作过程。
目前大多数CPU执行指令,需要经历指令存储,读取,译码,执行这一系列过程。这些过程中的每一步中均存在一定概率遇到随机错误,从而导致功能安全问题。设备运行过程中,也存在被黑客攻击所带来的信息安全问题。因此,芯片的CPU指令系统需要功能安全和信息安全的双重保障。
目前,越来越多的芯片需要提供功能安全和信息安全的保障。由此,现有技术中存在有大量指令存储读取和CPU的保护方法。例如有CPU双核互锁方法,指令加密与签名方法,指令增加校验位等方法。但是,现有保护方法,其无法检测也无法定位指令存储、读取、译码、执行过程中产生的随机错误。现有方式下随机错误只会随着指令的读取、译码、执行过程被直接执行,导致系统出现错误行为。现有的保护机制也无法主动检测到黑客的攻击行为,信息安全同样难以保障。
CPU技术及其指令架构和编译器等技术,正在快速发展中,CPU及其指令的保护技术也在不断推陈出新,不过,由于同时需要支持功能安全和信息安全保护的芯片,如何保护CPU及其指令系统方法目前还无成熟技术可以借鉴。
发明内容
本发明针对现有技术的不足,提供一种适用于功能和信息安全芯片的CPU指令保护方法及系统,本发明采用一种简单的指令编码与处理方法,使得CPU读取执行指令的整个过程都能够得到保护,不仅可以检测到随机错误发生,也可以检测到黑客攻击,可以同时适用于功能安全和信息安全的应用场景。本发明具体采用如下技术方案。
首先,为实现上述目的,提出一种适用于功能和信息安全芯片的CPU指令保护方法,其在向指令存储单元存储指令时,按照以下步骤进行指令编码:
将需要存储的原始指令与编码随机值进行编码运算,将编码运算所获得的编码指令值存储在指令存储单元中;
其中,所述编码随机值为预先获得的初始值,或所述编码随机值为按照散列函数对上一条原始指令以及上一条原始指令所对应的编码随机值进行计算而获得;
其还在读取指令后,按照以下步骤进行指令解码:
将读取指令存储单元所获得的编码指令值与解码随机值进行解码运算,得到解码后指令;
其中,所述解码随机值为预先获得的初始值,或所述解码随机值为按照散列函数对上一条解码后指令以及上一条解码后指令所对应的解码随机值进行计算而获得;
其中,所述编码运算和所述解码运算互为逆运算。
可选的,如上任一所述的适用于功能和信息安全芯片的CPU指令保护方法,其中,还包括以下步骤校验所述解码后指令是否正确:
在所述解码后指令执行完成后进行指令编码,比较其进行指令编码所获得的结果是否与指令存储单元中所存储的编码指令值相同,若相同则确认所述解码后指令正确,若不同则表示存在异常。
可选的,如上任一所述的适用于功能和信息安全芯片的CPU指令保护方法,其中,指令编码过程中,仅对程序中的首条原始指令,或程序中各分支所汇合的原始指令,或程序中函数调用的首条原始指令,采用预先获得的初始值作为编码随机值进行编码运算而获得编码指令值;
指令解码过程中,仅对程序中的首条编码指令值,或程序中各分支所汇合的编码指令值,或程序中函数调用的首条编码指令值,采用预先获得的初始值作为解码随机值进行解码运算而获得解码后指令。
可选的,如上任一所述的适用于功能和信息安全芯片的CPU指令保护方法,其中,所述散列函数的输出长度至少达到单条原始指令的最大长度。
可选的,如上任一所述的适用于功能和信息安全芯片的CPU指令保护方法,其中,若散列函数的输出长度与需要编码的原始指令的长度不同,则:
在向指令存储单元存储指令时,截取散列函数所输出的随机数中的固定位作为编码随机值,用于对需要编码的原始指令进行指令编码;并对应在读取指令后,截取散列函数所输出的随机数中同样的固定位作为解码随机值,用于对读取到的编码指令值进行指令解码。
可选的,如上任一所述的适用于功能和信息安全芯片的CPU指令保护方法,其中,指令解码过程中,对程序中函数调用前的最后一条编码指令值还将其所对应的解码后指令和/或解码随机值保存至堆栈中;
在该函数调用结束后,调取堆栈中所保存的解码后指令和/或解码随机值对下一条编码指令值进行指令解码。
可选的,如上任一所述的适用于功能和信息安全芯片的CPU指令保护方法,其中,所述散列函数包括:HASH函数(即,哈希函数)、CRC32/16函数(即,循环冗余校验函数)中的任意一种或其组合;
所述编码运算为异或运算,所述解码运算对应选择为异或运算。
可选的,如上任一所述的适用于功能和信息安全芯片的CPU指令保护方法,其中,所述编码随机值或解码随机值所对应的预先获得的初始值由保护开始指令设定;
所述保护开始指令在指令编码过程中,由编码器插入至程序中的首条原始指令之前,或插入至程序中各分支所汇合的原始指令之前,或插入至程序中函数调用的首条原始指令之前;
所述保护开始指令在指令解码过程中,由译码器插入至程序中的首条编码指令值,或插入至程序中各分支所汇合的编码指令值,或插入至程序中函数调用的首条编码指令值之前;
所述保护开始指令本身不参与与编码随机值或解码随机值进行的编码运算或解码运算。
同时,为实现上述目的,本发明还提供一种适用于功能和信息安全芯片的CPU指令保护系统,其包括:
编码器,其在在向指令存储单元存储指令时,按照以下步骤进行指令编码:将需要存储的原始指令与编码随机值进行编码运算,将编码运算所获得的编码指令值存储在指令存储单元中;
译码器,其在读取指令后,按照以下步骤进行指令解码:将读取指令存储单元所获得的编码指令值与解码随机值进行解码运算,得到解码后指令。
可选的,如上任一所述的适用于功能和信息安全芯片的CPU指令保护系统,其中,编码器中,对程序中的首条原始指令、程序中各分支所汇合的原始指令、程序中函数调用的首条原始指令均以预先获得的初始值作为所述编码随机值,程序中的其他原始指令所对应的所述编码随机值均为按照散列函数对上一条原始指令以及上一条原始指令所对应的编码随机值进行计算而获得;
译码器中,对程序中的首条编码指令值、程序中各分支所汇合的编码指令值、程序中函数调用的首条编码指令值均以预先获得的初始值作为所述解码随机值,程序中的其他编码指令值所对应的解码随机值均为按照散列函数对上一条解码后指令以及上一条解码后指令所对应的解码随机值进行计算而获得
有益效果
本发明利用散列函数产生生成编码随机值和相应的解码随机值,利用其与原始指令或与编码指令值进行编码或解码运算,相应实现指令的重新编码和解码。由于每一轮散列函数的输出都包含前面每一轮指令的信息,所以任意一步发生错误,都会影响后续的全部编解码过程,因此,其本发明中各条指令之间的编码随机值和解码随机值具有相应的延续性,能够将任一步骤内出现的异常延续到后续步骤中,从而实现对芯片功能安全和信息安全的检测。
进一步,本发明能够利用随机性的散列函数输出值进行异或等编码或解码运算,将原始指令替换为具有随机性的数据串,掩盖原始指令的传输功率,从而避免黑客直接利用对数据传输功率的监听而破译对应的指令数值。由此,本发明能够充分保障CPU的信息安全。此外,由于用于产生随机数的散列函数其输入长度可以设置为任意值,而输出值的各比特位之间均具有随机性,因此,对于不同指令长度混编的指令系统,本发明可以通过指定进行编码或解码运算的随机数所对应的散列函数的输出位数,而无差别地利用同样的散列函数运算实现对不同长度指令的编码译码保护。
考虑到程序中不同分支汇合时或函数调用时,各分支或不同函数所对应的编码随机值或译码随机值会受到分支或函数内不同指令的影响而存在差异,为保证汇合后或函数调用后编码译码正确,本发明还可在程序中各分支所汇合的位置或函数调用的首条指令之前增加保护开始指令,以对汇合后的指令和调用的函数重新开始新一轮编解码保护。由此可避免不同分支和函数之间出现编码、译码冲突。针对函数运行后返回主程序的情况,本发明还可进一步利用堆栈恢复出主程序进行编码译码所对应的随机数,从而继续主程序的编译码过程。
本发明中利用编码随机值和解码随机值与指令进行异或等编、解码运算的步骤具有可逆性。因此,本发明还可以通过对指令执行完成后的指令进行重新编码,通过校验重新编码结果是否与指令存储单元中所存储的相应编码指令值一致来判断原先的编译码过程是否出错。本发明能够通过该校验过程主动检测出异常,从而实现对指令整个生命周期的随机错误的检测,以支持功能安全保护,并实现对指令整个生命周期被黑客攻击的检测,以实现功能安全保护。本发明可以保护CPU指令存储、读取、译码、执行过程的功能安全和信息安全。
本发明的其它特征和优点将在随后的说明书中阐述,并且,部分地从说明书中变得显而易见,或者通过实施本发明而了解。
附图说明
附图用来提供对本发明的进一步理解,并且构成说明书的一部分,并与本发明的实施例一起,用于解释本发明,并不构成对本发明的限制。在附图中:
图1是本发明的适用于功能和信息安全芯片的CPU指令保护系统的工作方式示意图;
图2是采用发明的方法对一共指令序列进行编码的示意图;
图3是本发明的适用于功能和信息安全芯片的CPU指令保护方法对原始指令进行指令编码过程的示意图;
图4是本发明的适用于功能和信息安全芯片的CPU指令保护方法对编码指令值进行指令解码过程的示意图。
具体实施方式
为使本发明实施例的目的和技术方案更加清楚,下面将结合本发明实施例的附图,对本发明实施例的技术方案进行清楚、完整地描述。显然,所描述的实施例是本发明的一部分实施例,而不是全部的实施例。基于所描述的本发明的实施例,本领域普通技术人员在无需创造性劳动的前提下所获得的所有其他实施例,都属于本发明保护的范围。
本技术领域技术人员可以理解,除非另外定义,这里使用的所有术语(包括技术术语和科学术语)具有与本发明所属领域中的普通技术人员的一般理解相同的意义。还应该理解的是,诸如通用字典中定义的那些术语应该被理解为具有与现有技术的上下文中的意义一致的意义,并且除非像这里一样定义,不会用理想化或过于正式的含义来解释。
图1为根据本发明的一种适用于功能和信息安全芯片的CPU指令保护系统,其需要硬件配合编译器支持,可以实现对指令读取,译码,执行和校验过程的保护。该系统不仅可以检测指令整个生命周期的随机错误发生,以支持功能安全保护,也可以检测指令整个生命周期内被黑客攻击的发生。其不仅可以保护顺序执行指令代码,也可以保护包括跳转代码和函数调用的指令执行,可以支持不同长度指令系统,使得CPU指令功能安全性和信息安全性都得到大大提高。具体而言,实现该系统安全保护功能的核心部件包括:
编码器,用于在在向指令存储单元存储指令时,按照以下步骤进行指令编码:将需要存储的原始指令与编码随机值进行异或等编码运算,将异或等编码运算所获得的编码指令值存储在指令存储单元中;其中,该编码过程中所使用的编码随机值为预先获得的初始值,或所述编码随机值为按照散列函数对上一条原始指令以及上一条原始指令所对应的编码随机值进行计算而获得;
译码器,用于在读取指令后,按照以下步骤进行指令解码:将读取指令存储单元所获得的编码指令值与解码随机值进行异或等解码运算,得到解码后指令;其中,该解码过程中所使用的解码随机值为预先获得的初始值,或所述解码随机值为按照散列函数对上一条解码后指令以及上一条解码后指令所对应的解码随机值进行计算而获得。
所述的编码运算和解码运算并不应该被限制为异或一种形式,其他运算也可以,只要编码运算和解码运算互为逆运算,能够相互可逆得得出运算的原始数据即可。选择异或为编码函数时,可以用采用异或输入为编码随机值和原始指令,此时,相应的,解码函数为编码函数逆运算,即异或的逆运算,也是异或。
下面以图2所示的带有分支和函数调用的原始指令序列为例,详细说明上述系统所提供的适用于功能和信息安全芯片的CPU指令保护方法的具体执行过程:
1、本发明在对第一条原始指令进行编码或译码之前,需要在其之前增加一条指令I0,标识出指令保护开始,并配以任意随机值的初始向量值IV,以便编码过程中能够基于这条指令计算散列函数,并将其用作对下面第一条原始指令进行编解码的基数,即,作为本发明的编码随机值或解码随机值。
2、对其他指令所进行的存储编码过程同样基于上述的散列函数。对于其他指令而言,编码过程中,需要将散列函数的输入值取为上一轮散列函数所输出的编码随机值和上一轮进行编码的原始指令值,即Hn = h(Hn-1,In-1),其中,h表示散列函数,Hn表示第n轮散列函数输出,In-1表示第n条指令。散列函数的输出可设定为与系统中最长可能指令长度相同。例如,如果系统的指令长度最多为32bit,则散列函数算法可以选择设置其输出长度为32bit。
本轮编码指令的结果由本轮散列函数输出的随机数与本轮原始指令之间进行异或而得出,即Cn = Hn ^ In。
对于第一步中的指令保护开始指令I0,不对其做编码运算,但要参与到下一条指令的编码计算,利用该指令保护开始指令I0所提供的初始值H0,计算出用于第一条指令的编码随机值H1=h(H0,I0)。其中的H0为通过保护开始指令I0所预先获得的散列函数初始值,为一个常数。
3、每次CPU读取指令后,与上述编码过程对应,也都运行散列函数Hn=h(Hn-1,In-1),得到每一轮输出Hn,然后用该值异或本轮编码指令值,即执行In = Hn ^ Cn,即可得到解码后指令,送到指令译码进行译码。
4、当遇到跳转指令时,则继续对程序所跳转至的各个分支的下的每一条指令同样使用上面的方法进行编码或者解码过程。由于第一条保护开始指令I0没有做编码,通过I0可以计算出H1, 通过I1 和 H 1可以计算出H2,通过I2和H2可以计算出H3……
5、当遇到有多条分支都有可能合法的跳转汇合到同一个目的指令时,还需要在该目的指令前插入另一条保护开始指令,以设置该汇合节点之后的指令能够以统一的编码随机值或译码随机值重新开始指令编解码。由此,本发明能够避免不同分支所携带的不同编码随机值或译码随机值之间相互影响,使得不同分支汇合后都能够以统一的起始值适应指令分支跳转。
6、当需要支持函数调用时,本发明可以设置一个堆栈专门保存和恢复当前调用现场的散列函数值,并在调用的函数的首条指令前插入一条保护开始指令,使得被调用的函数能够独立于主程序,按照全新的初始值进行编解码。这样,函数返回后可通过堆栈恢复调用指令发生时的散列函数值,从而继续对主程序中其余各个指令进行相应的编解码。
7、在执行完成后,还可进一步的将执行后的指令I`n送到校验模块,对其重新进行编码,即计算C`n = h(H`n-1,I`n-1) ^ I`n ,并将重新编码所获得的数据与原先读取后的编码指令Cn进行对比。如果对比两者不一致,则说明执行出错。可针对该错误指令进行安全芯片重启或触发相应中断,将芯片切换至适宜的安全模式。
本发明中,编码之后的指令并未增加长度,其能够与原有指令保持相同长度,因此,本发明除了必要的保护指令开始命令,并不会增加指令的存储空间或读取开销,不会损失执行性能和指令存储空间。
此外,指令的重新编码和解码,采用上一轮的结果作为下一轮的输入的形式,保证了只要此过程中有一个错误都能够传递到后面的结果。执行的顺序性和正确性。随机错误,或者黑客尝试攻击跳过某指令都会被检测到。
由于初始化向量可以随机,即相同的代码编码后会不相同,这样读取代码是所产生的功耗也会不相同。本发明能够利用随机数进行异或运算,将原始指令替换为具有随机性的数据串,掩盖原始指令的传输功率,从而避免黑客直接利用对数据传输功率的监听而破译对应的指令数值。由此,本发明能够增加抗侧信道攻击的能力,充分保障CPU的信息安全。
用于计算的散列函数,其输入长度可以任意,可以支持不同指令长度混编的指令系统。以一个32bit与16bit指令长度混编系统为例,当采用HASH32算法进行散列运算获得相应的编码随机值和解码随机值后,每条指令编解码HASH输出为32bit。当编码或解码所对应的指令为16bit长度时,可约定本系统中统一选用HASH32bit的低16bit进行异或得到编解码结果,也可约定本系统中统一选用HASH32bit的高16bit进行异或得到编解码结果。系统内部统一比特位的选择机制,就可将本轮16bit指令参与到下一轮HASH32的计算中去,以此循环而不用担心不同长度输入会影响编、解码随机值。
上述的散列函数还可以选取例如CRC32/16的简单算法,以方便实时计算并适应典型的指令长度(32bit/16bit)。
以下以RISC-V CPU为例,通过图3以及图4所示的具体的编解码过程说明本发明的适用于功能和信息安全芯片的CPU指令保护方法的具体执行过程。
RISC-V CPU中,指令的长度为32bit或者16bit,散列函数采用CRC32(生成多项式为x32+ x26+ x23+ x22+ x16+ x12+ x11+ x10+ x8+ x7+ x5+ x4+ x2+ x + 1)定义一条指令为开始保护(16bit 初始向量+9bit标识码+7bit操作码)
如果初始向量为1,那么定义开始保护指令为0x0001C0DE
下面是一段原始的RISCV指令及其机器码结果,
0000000080000000 < Start > :
80000000 : 00009197 ->
80000004 : d0018193
80000008 : f14022f3
8000000C : 02029263
80000010 : 50018113
80000014 : 84018293
80000018 : 00009317
8000001C : 73030313
80000020 : 0002a023
80000024 : 0291
80000026 : fe629de3
8000002a : 76e000ef
8000002e : a001
80000030 : 10500073
80000034 : a001
采用本发明的方法进行指令编码后结果如表1所示:
表1-进行指令编码后的结果
原始代码 |
CRC值 |
编码后代码 |
0001code |
- |
0001code |
00009197 |
fc1e6d28 |
fc1efcbf |
d0018193 |
f51f71f0 |
251ef063 |
f14022f3 |
6f88e4c5 |
9ec8c636 |
2029263 |
386c8aea |
3a6e1889 |
50018113 |
d38cb082 |
838d3191 |
84018293 |
b653199a |
32529b09 |
00009317 |
a08e52ad |
a08ec1ba |
73030313 |
fdee60c4 |
8eed63d7 |
0002a023 |
7c58f3bf |
7c5a539c |
0291 |
ec11625c |
60cd |
fe629de3 |
e1e4cbc7 |
1f865624 |
76e000ef |
cb2a7c33 |
bdca7cdc |
a001 |
d9364380 |
e381 |
10500073 |
c9992c73 |
d9c92c00 |
a001 |
b8fa9d93 |
3d92 |
可以看到编码后的指令存储在存储器内,与原始指令完全不同,每条指令的汉明重量也发生编码,在CPU读取这些指令时,发生的功耗与原始指令不会相同,这样就增加了根据CPU芯片功耗分析指令执行的难度。增加了抗测信道攻击的能力。
读取指令后进行解码,解码结果如表2所示:
表2-解码结果
编码后代码 |
CRC值 |
解码后结果 |
0001code |
- |
0001code |
fc1efcbf |
fc1e6d28 |
00009197 |
251ef063 |
f51f71f0 |
d0018193 |
9ec8c636 |
6f88e4c5 |
f14022f3 |
3a6e1889 |
386c8aea |
2029263 |
838d3191 |
d38cb082 |
50018113 |
32529b09 |
b653199a |
84018293 |
a08ec1ba |
a08e52ad |
00009317 |
8eed63d7 |
fdee60c4 |
73030313 |
7c5a539c |
7c58f3bf |
0002a023 |
60cd |
ec11625c |
0291 |
1f865624 |
e1e4cbc7 |
fe629de3 |
bdca7cdc |
cb2a7c33 |
76e000ef |
e381 |
d9364380 |
a001 |
d9c92c00 |
c9992c73 |
10500073 |
3d92 |
b8fa9d93 |
a001 |
可以看出解码后的指令与原始指令相同
随后再次对指令进行编码,然后与读取的编码指令进行校验得到表3结果:
表3-对指令进行编码并与读取的编码指令进行校验的结果
当某一步编码某条指令发生功能安全错误,反转了一个bit,和假设读取的编码后0x8eed63d7指令由变为
0x8eed63d“3”,那么后面解码后代码和CRC计算值都会变化。变化情况如表4所示:
表4-解码后代码和CRC计算值
原始代码 |
CRC值 |
编码后代码 |
解码后结果 |
0001code |
- |
0001code |
0001code |
00009197 |
fc1e6d28 |
fc1efcbf |
00009197 |
d0018193 |
f51f71f0 |
251ef063 |
d0018193 |
f14022f3 |
6f88e4c5 |
9ec8c636 |
f14022f3 |
2029263 |
386c8aea |
3a6e1889 |
2029263 |
50018113 |
d38cb082 |
838d3191 |
50018113 |
84018293 |
b653199a |
32529b09 |
84018293 |
00009317 |
a08e52ad |
a08ec1ba |
00009317 |
73030313 |
fdee60c4 |
8eed63d“3” |
7303031“7” |
0002a023 |
f33a64e8” |
“7c5a539c” |
“8f603774” |
0291 |
“685b6ca6” |
“60cd” |
“0c6b” |
fe629de3 |
“e80f6bbd” |
“1f865624” |
“f7893d99” |
76e000ef |
“d286f328” |
“bdca7cdc” |
“6f4c8ff4” |
a001 |
“d29e9486” |
“e381” |
“311f” |
10500073 |
“8774c72a” |
“d9c92c00” |
“5ebdeb2a” |
a001 |
“d1fc03cc” |
“3d92” |
“ec6e” |
可以看到后面的指令解码全都混乱了,无法正确的进行解码,那么不能正常解析代码将检查出代码出现问题。
当执行过程中由于被攻击跳过了一条指令0x0291,那么校验结果如表5所示:
表5-校验结果
读取的编码代码 |
CRC值 |
解码后执行代码 |
执行后的编码代码 |
校验结果 |
0001code |
- |
0001code |
0001code |
正常 |
fc1efcbf |
fc1e6d28 |
00009197 |
fc1efcbf |
正常 |
251ef063 |
f51f71f0 |
d0018193 |
251ef063 |
正常 |
9ec8c636 |
6f88e4c5 |
f14022f3 |
9ec8c636 |
正常 |
3a6e1889 |
386c8aea |
2029263 |
3a6e1889 |
正常 |
838d3191 |
d38cb082 |
50018113 |
838d3191 |
正常 |
32529b09 |
b653199a |
84018293 |
32529b09 |
正常 |
a08ec1ba |
a08e52ad |
00009317 |
a08ec1ba |
正常 |
8eed63d7 |
fdee60c4 |
73030313 |
8eed63d7 |
正常 |
7c5a539c |
7c58f3bf |
0002a023 |
7c5a539c |
正常 |
|
|
0291 |
60cd |
—— |
60cd |
ec11625c |
fe629de3 |
1273ffbf |
错误 |
1f865624 |
60b8153c |
76e000ef |
165815d3 |
错误 |
bdca7cdc |
c4203181 |
a001 |
6421 |
错误 |
e381 |
6e891034 |
10500073 |
7ed91047 |
错误 |
d9c92c00 |
9138c5f9 |
a001 |
3139 |
错误 |
3d92 |
—— |
—— |
—— |
异常 |
由此可见,利用本发明进行编解码,只要尝试跳过一条指令执行,校验逻辑可以马上可以检测错误。
综上,本发明利用散列算法,对指令进行循环编码,以对其进行存储。本发明在读取指令后实时进行运算解码,得到原始指令执行,执行完成后可对代码再进行重新编码,并对重新编码所获得的结果与原先读取的编码指令进行比较,实现对编译过程中错误的主动检测,利用少量的硬件支持CPU指令的功能安全和信息安全保护。并且,本发明可以同时支持对于CPU指令读取,译码,执行的功能安全保护和信息安全保护,能够提高芯片系统的功能安全芯片运行的安全型和可靠性。对于可适应不同指令长度和架构均,本发明可以同时支持不同长度的指令架构,无差异地对安全芯片系统提供功能安全和信息安全芯片的CPU指令保护。
以上仅为本发明的实施方式,其描述较为具体和详细,但并不能因此而理解为对本发明专利范围的限制。应当指出的是,对于本领域的普通技术人员来说,在不脱离本发明构思的前提下,还可以做出若干变形和改进,这些均属于本发明的保护范围。