DCSM模块的使用说明

other parts discussed in post: tms320f28377s
作者:华北区 ep 工程师 brian wang ,华北区 c2000 工程师 young hu 
一、功能描述:
csm加密是c2000系列芯片最基础的加密方式,也是在前代产品(如f2803x/f2806x)中广泛采用的加密方式。在最新的28004x、2837x等芯片中增加了双码安全模块(dcsm),该功能支持将芯片中的memory划为两个独立区域,并设置各自独立的的128位csm密码。该功能可以阻止未授权人员访问加密内容,进而有效防止您的代码被重复或逆向编译;与此同时,需要维护与升级的代码可以存储于另一个独立区域内,并授权给相关人员使用。合理运用此功能,可以进一步地提高产品的安全性以及易用性。
二、功能使用:
2.1 芯片存储的分区设置
下面以control suite中tms320f28377s的 blinky_with_dcsm工程为例,讲解dcsm模块的用法:
首先必须明确,虽然dcsm模块中设计了相关机制允许用户反复设置和使用该功能,但对于dcsm模块的不当操作仍然可能锁死芯片,因此建议您在工程开发的末尾阶段再进行dcsm模块的相关设置和操作。
为了充分发挥双码安全模块的作用,需要根据工程需要对mcu中的资源进行分区配置。通过配置grabramx/grabsectx寄存器,按需求将ram/flash分别划入不同的zone中,从而实现用两套独立密码对不同区域分别进行安全管理。
图1 grabramx/grabsectx寄存器设置
以工程blinky_with_dcsm为例,假如我们想要将flash a 分配至zone1进行保护,flash b分配至zone2进行保护。参考手册中关于zx_grabsectr register及zx_grabsectr register,需要对dcsm_zx_zoneselectblock.asm进行如下修改。将zone 1grabsect中flash a对应的[1:0]位改为01或10;将zone 2 grabsect中flash b对应的[3:2]位改为01或10;特别需要注意的是,由于.asm中一个section是按位写入的,因此在对.asm文件进行修改时,必须以section为单位进行修改,即便有reserve的部分也需要将注释删掉进行编译,否则写入时只会按位写入已编译的内容,发生错位,难以修改。
      .sect dcsm_zsel_z1       .long 0xffffffff      ;z1-exeonlyram        .long 0xffffffff      ;z1-exeonlysect        .long 0xffffffff      ;z1-grabram        .long 0xfffffffe      ;z1-grabsect
.sect dcsm_zsel_z2        .long 0xffffffff      ;z2-exeonlyram        .long 0xffffffff      ;z2-exeonlysect        .long 0xffffffff      ;z2-grabram        .long 0xfffffff7      ;z2-grabsect
2.2分区的基本设置
在完成了对要保护存储的分区之后,我们需要了解如何给两个区域设置不同的密码。
对于两个保护zone,每个都有一个专属的otp block,以对各zone进行安全设置,具体包含的资源及作用如下:
zx-linkpointer1-3
配置zx otp中zone select block的位置
zx-pswdlock
用于使能password lock
zx-crclock
用于使能safe crc
zoneselectblock(0x20-0x1f0)
zone select block 预留位置
zx-exeonlyram
用于使能ram的execute-only 保护
zx-exeonlysect
用于使能flash的execute-only 保护
zx-grabram
用于配置ram的所在分区
zx-grabsect
用于配置flash的所在分区
zx-csmpassword
用于配置分区的csm密码
为了能够让用户多次使用该功能、设置不同的密码,如图2,28004x系列mcu在users otp中设置了多个存储密码及相关信息的位置(zoneselect block),用户可以通过linkpointer自由选择当前使用哪一个zone select block。
linkpointer与zone select block 对应关系如图3所示。作为一种校验措施三个linkerpointer的值设为相同,若linkerpointer1/2/3值不相同,则linkpointer的值将被置为全1,系统将默认选择zone-select block 1(0x20)。此外,由于zx-linkerpointer位于otp区域,因此该寄存器的各位只能由1写成0,而不能逆向操作。因此,只有zx-linkpointer的值从“全f”写起,并在每次重新设置时按照下表顺序逐位写0,才能够充分利用到otp中的所有zone-select block。
图2 zonex otp flash
图3 zx-linkpointer与zone select block对应关系
以工程blinky_with_dcsm为例,假如是第一次使用dcsm功能,为了充分利用所有blocks,选取zone_select block0作为当前使用的block,在dcsm_zx_zoneselectblock.asm中保证z1-linkpointer值为全f,此时选取的zone_select block起始地址为0x70820。
  .sect dcsm_otp_z1_linkpointer   .long 0x1fffffff     ;z1-linkpointer1   .long 0xffffffff     ;reserved   .long 0x1fffffff     ;z1-linkpointer2   .long 0xffffffff     ;reserved   .long 0x1fffffff     ;z1-linkpointer3   .long 0xffffffff     ;reserved  
类似地,如果后续工程需要对密码以及分区情况进行修改,我们可以启用zone_select block1,将linkerpointer的最后一位写0,对应的修改如下:
  .sect dcsm_otp_z1_linkpointer  .long 0x1ffffffe     ;z1-linkpointer1   .long 0xffffffff     ;reserved   .long 0x1ffffffe     ;z1-linkpointer2   .long 0xffffffff     ;reserved   .long 0x1ffffffe     ;z1-linkpointer3   .long 0xffffffff     ;reserved
此时需要注意还需要将cmd文件中对应zone select block地址的内容进行修改,保证写入的flash地址与当前的zone select block正确对应。
/* dcsm z1 zone select contents (!!movable!!) */   /* z1 otp.  z1 password locations / flash and ram partitioning */   dcsm_zsel_z1_p0         : origin = 0x78030, length = 0x000010
最后在sections中将要写入区域对应处的type=dsect 删除,否则flash写入不会进行。
sections   {      b0_dcsm_otp_z1_linkpointer   : > b0_dcsm_otp_z1_linkpointer   page = 0, type = dsect /* delete type=dsect when writing in otp */
特别需要注意的是:由于以上涉及到的寄存器都位于otp(one-time programmable)flash中,不能进行反复更改,因此建议在开发后期代码以及内存分配确定之后,再进行相关的设置。
2.3 加密功能及其使用
在完成了对mcu中memory的分区以及zone select block位置的设置后,下面来看dcsm所支持的几种加密模功能:
1)csm密码加密与解密:
csm加密是dcsm加密的基础,在完成对mcu 存储的分区之后,需要为分区设置各自的密码才能使能加密功能。密码寄存器zx-csmpswd0/1/2/3位于各自的otp的zone select block中,具体位置由该区域的linkpointer决定。对于2837x系列,当zx-csmpswd0/1/2/3的值为默认值1,该区域处于解锁状态。当寄存器值为全0,该区域会被锁死,因此用户不应当使用全0密码。
以工程blinky_with_dcsm为例,要设置zone1的密码,我们需要在dcsm_zx_zoneselectblock.asm中将zx-csmpswdx寄存器改为想要设置的密码:
.sect dcsm_zsel_z1            .long 0xffffffff      ;z1-exeonlyram         .long 0xffffffff      ;z1-exeonlysect         .long 0xffffffff      ;z1-grabram         .long 0xffffffbf      ;z1-grabsect            .long 0x11223344      ;z1-csmpswd0 (lsw of 128-bit password)         .long 0x11223344      ;z1-csmpswd1         .long 0x55667788      ;z1-csmpswd2         .long 0x55667788      ;z1-csmpswd3 (msw of 128-bit password)
同样需要在cmd中对相应的dcsm_zsel_zx 的sections 进行修改,删除type=dsect,对flash的操作才能够进行。这样就完成了zonex 密码的设置工作。
     b0_dcsm_zsel_z1      : > b0_dcsm_zsel_z1_p0            page = 0
进行加密后,通过仿真器读取zone 1 otp flash结果如下:
图3 加密后的otp区域
可以看到此时zone 1 otp flash中除了 csmpswdx寄存器中的密码,其它部分均进行了加密操作。之所以采用这样的设计,是为了在开发初期开发者可以利用这一特性随时查看csm,避免因为密码遗忘或者写入操作造成芯片被锁死。对于密码区域的加密需要通过password lock 功能进行,将在后文进行进一步描述。
此时,如果试图通过仿真器读取加密区域flash b,可以看到flash区域也进行了加密(返回全0):
图3 未加密的flash(左)与加密后的flash(右)
要对csm进行解密,需要经过password match flow(pmf)流程,程序将从两个zone读取csm pwl并与写入csmkeyx寄存器的密码进行比对,若密码完全一致,则为该区域解密,否则解密失败。
图4 password match flow 流程图
解密操作可以通过几种方法进行,首先可以在debug界面单击tools -> on chip flash -> 在对应位置处输入密码,点击unlock:
图5在on chip flash中进行密码匹配
也可以在.gel文件中找到写入csmkey寄存器的代码段,并自行修改密码:
*(unsigned long *)0x5f010 = 0x11223344;  // virtual password *(unsigned long *)0x5f012 = 0x55667788;   *(unsigned long *)0x5f014 = 0x11223344;   *(unsigned long *)0x5f016 = 0x55667788;
另外,也可以通过在芯片内部执行一段解密程序完成解密操作,具体代码可参照.gel文件。
以blinky_with_dcsm为例,如果把代码段写入flash a,并将flash a划入zone1设置密码保护。在正确输入密码时,烧录操作可以正常进行。
而在不输入正确密码时,会出现解锁失败的提示,烧录也会报错。
图6 未解锁状态下进行烧录报错
note:特别需要注意的是,在使用280049系列芯片时,与传统c2000系列芯片不同,其zxotp_csmpswd1寄存中写入的默认密码不是全“1”。由于otp寄存器的特殊性,只能在默认设置的基础上将1改成0,否则可能发生flash写入错误。
图8 28004x csmpwsd1默认密码表(部分)
2)仿真代码保密逻辑 emulation code security logic(ecsl)
在csm的基础上,芯片利用csm密码的后64位设计了仿真加密逻辑。如果试图在加密代码中halt就会触发该保护,断开仿真连接。用户需要在csmkey(0/1)中写入正确的64位密码才能启用仿真,但此时并不会解锁csm保护,对csmkey(0/1)的写入方法可以参考上一条。
图8 在加密代码中halt触发仿真保护
特别注意,在debug一个加密mcu时,仿真器需要一些时间控制cpu,但此时cpu可能已经运行并触发ecsl保护导致断连。要解决此问题,请使用wait boot mode boot选项,在此模式中,cpu会运行在一个循环中而不进入应用程序,从而避免触发保护。具体设置方法请参考技术手册boot rom部分,launchpad可以通过拨动相应的开关进入此模式。
3)cpu加密逻辑 cpu secure logic(cpusl)
cpu加密逻辑可以防止未授权者通过watch window读取cpu寄存器,在程序指针指向保护区域时,所有对于cpu寄存器的访问都被禁止(程序指针除外)。在此情况下,最好不要对cpu寄存器进行写入。另外,如果csm被解锁,此外,cpusl也将被关闭。
图8 加密代码运行过程中cpu registers不可见
4)仅执行保护 execute-only protection
对于存储关键数据的ram或flash,ti提供了execute-only protection。当该逻辑启用,任何对该区域数据的读取都将被禁止。例如如果试图使用另一个加密区域中的代码对execute-only protection加密区域中的代码进行复制、读取等操作都将被禁止。通过写入exeonlysect以及exeonlyram寄存器对应位的值,可以启用该功能。
5)密码锁 password lock
如前文所述,若只采用csm加密,可以通过memory browser发现此时对应csm密码的位置并没有进行加密。在开发完成后,开发者需要通过password lock功能对此区域进行加密,以防他人读取密码并进行解密。启用该保护的方法是向对应区域的pswdlock寄存器0:3位写入0xf以外的值。
图9 未开启password lock时的zsb0寄存器值
以blinky_with_dcsm为例,要设置zonex的密码,需要在dcsm_zx_zoneselectblock.asm中将zx-pswdlock[3:0]该为非全1,并在cmd中删去相应部分的.dsect:
.sect dcsm_otp_z1_pswdlock   .long 0xfffffffe     ;z1-pswdlock   .long 0xffffffff     ;reserved
图10开启password lock时的zsb0寄存器值
至此,我们就完成了dcsm中各种安全功能的介绍和设置,特别注意,由于pswdlock等寄存器并不位于zone select block当中,因此只能进行一次写入,不能进行更改,因此应该在程序开发后期再加此类保护。
三、小结
dcsm加密相较于传统的csm加密具有更完善的保密措施和更灵活的使用方法。双密码的引入允许用户用不同密码管理不同部分的代码,为产品的代码安全以及后期的升级维护都带来了极大的便利。本实例以2837x系列芯片为对象,描述了dcsm模块常见的使用方法。28004x系列芯片仅在dcsm otp区域的数量和使用方法上与2837x略有不用,也可参照此说明进行相应操作。
另外部分c2000芯片也可以使用unique id作为种子进行进一步的加密,具体方法不在此展开。


5G毫米波频率规划问题探讨
DP/PPI转光纤模块连接200PLC组态王光纤通信在冷却塔控制系统案例
AP6934 PWM降压型 恒流恒压 三节锂电池充电管理芯片
波峰焊原理_波峰焊温度
对比骁龙820:华为麒麟950到底差在哪?
DCSM模块的使用说明
LED驱动器IC需求的大幅增长
计数器同步清零和异步清零的区别
不锈钢薄板焊接工艺流程_不锈钢薄板焊接顺序
晶体管点焊机更适合复杂焊接工艺
Hovding:摩托车专用的“隐形头盔”
坤坤智能锁厂家告诉你如何识别全自动智能锁好不好用
电工接线口诀:相交流电源的两种接法和两种出线方式
曝光:俄罗斯最新研究成果农用无人机FLYP
大数据的5v特征你知道多少
将AI嵌入物联网融合后会发生什么?
宏集Panorama SCADA在制药生产过程中的应用
哪些场景成为水下无人机的主要战场?
AI将帮助延长传感器和物联网电源的寿命
linux 显示文件夹所有文件的属性