概述
目前越來越多的微控器(MCU)應用需要使用到復雜的算法及中間件解決方案(middleware solution),因此,如何保護軟件方案商開發(fā)出來的核心算法等知識產權代碼(IP-Code),便成為微控制器應用中一項很重要的課題。因為這一重要的需求,AT32F423系列提供了安全庫區(qū)(SLIB)的功能,以防止重要的IP-Code被終端用戶的程序做修改或讀取,進而達到保護的目的。本文檔將詳細闡述AT32F423系列安全庫區(qū)的應用原理和軟件使用方法。
應用原理
安全庫區(qū)的應用原理
- 設定以密碼保護主閃存中指定范圍的程序區(qū)(即安全庫區(qū)),軟件方案商可將核心算法存放到此區(qū)域,以達到保護的功能,其余空白程序區(qū)可以提供給終端商客戶進行二次開發(fā)。
- 安全庫區(qū)劃分為唯讀區(qū)(SLIB_READ_ONLY)及指令區(qū)(SLIB_INSTRUCTION),并可選擇部分或是整個安全庫區(qū)存放唯讀區(qū)或者指令區(qū)。
- 唯讀安全庫區(qū)(SLIB_READ_ONLY)的數據能透過I-Code和D-Code總線讀取,不能寫入。
- 指令安全庫區(qū)(SLIB_INSTRUCTION)內的程序代碼僅能被MCU透過I-Code總線抓取指令(僅能被執(zhí)行),不能透過D-Code總線以讀取數據的方式讀取(包含ISP/ICP/調試模式以及從內部RAM啟動的程序),以讀取數據的方式去訪問SLIB_INSTRUCTION時,讀到的數值全都是0xFF。
- 安全庫區(qū)的程序代碼及數據,除非輸入正確的密碼,否則無法被擦除。在密碼不正確時,對安全庫區(qū)執(zhí)行寫入或擦除,將會在FLASH_STS寄存器的EPPERR位置"1"提出警告。
- 終端用戶執(zhí)行主閃存的整片擦除時,安全庫區(qū)的程序代碼及數據不會被擦除。
- 當安全庫區(qū)的保護功能被啟動后,可以透過在SLIB_PWD_CLR寄存器寫入先前設置的密碼來解除保護功能。解除安全庫區(qū)的保護時,芯片將會執(zhí)行主閃存的整片擦除(包含安全庫區(qū)的內容)。因此即使軟件方案商設置的密碼被泄漏,也不會有程序代碼外泄的疑慮。
下圖是包含安全庫區(qū)的主閃存區(qū)映射示意圖,安全庫區(qū)的程序代碼可以很容易地被終端用戶調用并執(zhí)行, 但不能直接被讀取,因而達到保護的功能。圖1. 帶有安全庫區(qū)的主閃存區(qū)映射安全庫區(qū)的范圍大小是以扇區(qū)(sector)為單位做設定,每一扇區(qū)的大小以實際MCU型號為準。表1是AT32F423系列各型號的主閃存大小、每扇區(qū)大小及可設置范圍。另外啟動程序代碼區(qū)在開啟了主存擴展功能后,整個20KB區(qū)域也是可以作為安全庫區(qū)。表1. AT32F423各型號閃存大小總表
如何啟動安全庫區(qū)保護
默認狀態(tài)下,安全庫區(qū)設定寄存器始終是不可讀且被寫保護。要想對安全庫區(qū)設定寄存器進行寫操作,首先要對安全庫區(qū)設定寄存器解鎖,對SLIB_UNLOCK寄存器寫入解鎖0xA35F6D24值,通過查看SLIB_MISC_STS寄存器的SLIB_ULKF位確認解鎖成功,隨后便允許對安全庫區(qū)設定寄存器寫入設定值。啟動主閃存安全庫區(qū)的步驟如下:
- 檢查FLASH_STS寄存器的OBF位,以確認沒有其他正在進行的閃存操作;
- 對SLIB_UNLOCK寄存器寫入0xA35F6D24,以進行安全庫區(qū)解鎖;
- 檢查SLIB_MISC_STS寄存器的SLIB_ULKF位,以確認解鎖成功;
- 在SLIB_SET_RANGE寄存器設定要保護的區(qū)域,包含SLIB的起始和結束地址以及SLIB指令區(qū)的起始地址;
- 等待OBF位變?yōu)椤?’;
- 在SLIB_SET_PWD寄存器設定安全區(qū)域密碼;
- 等待OBF位變?yōu)椤?’;
- 燒錄將存入安全庫區(qū)的代碼;
- 進行系統(tǒng)復位,重裝載安全庫區(qū)設定字;
- 讀出SLIB_STS0/STS1寄存器用于判斷安全庫區(qū)設定結果。
注意事項:
- 可在主閃存和主閃存擴展區(qū)中設置安全庫區(qū),實際可設置范圍參見表1;
- 安全庫區(qū)代碼必須以扇區(qū)為單位進行燒錄,且起始地址必須與主閃存地址或者擴展區(qū)地址對齊;
- 中斷向量表是數據型態(tài)且通常會被放置在閃存的第一扇區(qū)(扇區(qū)0)內,請勿將閃存的第一扇區(qū)設定為安全庫區(qū)的指令區(qū);
關于安全庫區(qū)設定寄存器的詳細說明,請參閱AT32F423系列技術手冊。啟動安全庫區(qū)的程序可參考安全庫區(qū)應用范例project_l0中位于main.c中的slib_enable()函數。亦可使用雅特力的ICP或ISP刻錄工具做設定,后面章節(jié)將會有詳細的說明。
如何解除安全庫區(qū)保護
當安全庫區(qū)的保護功能被啟動后,可以透過在SLIB_PWD_CLR寄存器寫入先前設置的密碼來解除保護功能。解除安全庫區(qū)的保護時,芯片將會執(zhí)行主閃存的整片擦除(包含安全庫區(qū)的內容)。解除主閃存安全庫區(qū)的步驟如下:
- 檢查FLASH_STS寄存器的OBF位,以確認沒有其他正在進行的編程操作;
- 在SLIB_PWD_CLR寄存器寫入先前設置的安全區(qū)域密碼;
- 進行系統(tǒng)復位,重裝載安全庫區(qū)設定字;
- 讀出SLIB_STS0寄存器用于判斷安全庫區(qū)設定結果。
編排及執(zhí)行安全庫區(qū)的程序
如前面章節(jié)所提到,在指令安全庫區(qū)(SLIB_INSTRUCTION)內的的程序代碼可以被MCU經由I-Code總線抓取,但不能經由D-Code總線以讀取數據的方式去讀出,這樣的保護是全面性的,也就是說在指令安全庫區(qū)之內的程序代碼,也不能讀取同樣被放置在指令安全庫區(qū)之內的數據,例如C程序代碼常被編譯成的文字池(literal pool)、分支表(branch table)或常數(constant)等之類當指令被執(zhí)行時會經由D-Code總線去讀取的數據。這代表指令安全庫區(qū)之內只能放置指令,不能放置任何數據。因此用戶在編排要放置在指令安全庫區(qū)之內的程序代碼時,必須配置編譯程序(compiler)的設定去產生只執(zhí)行(execute-only)的代碼以避免上述那些型態(tài)的數據產生。圖2及圖3是一般常見的文字池跟分支表的例子:switch()是C程序中常用的跳轉指令,此例子中的sclk_source變量是去讀取CRM_CFG寄存器,圖2可看到編譯出來的匯編代碼(assembly code) “LDR R7, [PC, #288]”,會用程序計數器(program counter, PC)間接尋址的方式去取得CRM_CFG寄存器的地址,而CRM_CFG的地址會被以常數的方式存放在鄰近的指令區(qū)(也在指令安全庫區(qū)之內),因此執(zhí)行switch()指令時就會發(fā)生數據的讀取。如果指令安全庫區(qū)內有這類的程序代碼,在執(zhí)行的時候就會產生錯誤。第三章的范例程序將會說明如何設定編譯程序的配置來避免這樣的問題。圖2. 文字池例子(1)圖3. 文字池例子(2)
不可將中斷向量表設置為安全庫區(qū)的指令區(qū)
中斷向量表包含每個中斷處理程序的入口點地址,由MCU通過D-Code總線讀取。通常,中斷向量表位于主閃存第一扇區(qū)(sector 0)的起始地址0x08000000,因此在設置指令安全庫區(qū)時,必須遵守以下的規(guī)則:
- 不可將主閃存的第一扇區(qū)設置為安全庫區(qū)的指令區(qū)。
安全庫區(qū)代碼與用戶區(qū)代碼的關聯性
受安全庫區(qū)保護的程序代碼(IP-Code)可以從位于用戶代碼區(qū)(安全庫區(qū)之外的區(qū)域)的函數庫中調用函數。在這種情形下,IP-Code將會包含這些函數的地址,允許PC(程序計數器)在執(zhí)行IP-Code時跳轉到這些函數。一旦安全庫區(qū)被啟動,這些函數的地址就不能被改變,此時,這些位于用戶代碼區(qū)的函數的地址就必須固定下來,否則PC將跳轉到錯誤的地址而無法正常工作。因此在設置安全庫區(qū)的時候,應該將所有與IP-Code相關聯的函數都一起編排到安全庫區(qū)之內以避免此情況發(fā)生。下圖顯示出一個被保護的函數Function_A()調用到用戶區(qū)內的函數Function_B()的例子。圖4. 安全庫區(qū)的函數調用用戶區(qū)函數的例子此外,另一個最常見的情形就是使用到C語言的標準函式庫,例如memset()及memcpy()這類函數。如果IP-Code跟用戶區(qū)代碼都有調用到這類函數,就會有上述問題的困擾。列舉兩種常用的解決方法:1) 將其編譯到安全庫區(qū)范圍內,具體如何實現可以查看keil或IAR的相關文檔。2) 避免在IP-Code內使用C的標準函式庫,若非要使用,就必須將用到的函數改寫為其他名稱,以下是一個范例,在IP-Code 中寫一個my_memset()函數取代原先的memset()。圖5. 自定義函數范例
方案商和終端用戶代碼整合及下載操作流程
方案商和終端用戶的代碼設計完成后,需要下載到同一個MCU中,這就涉及到各自代碼的安全性問題。以下列舉兩種常用下載操作流程供用戶參考,仍然是以上面Project_L0和Project_L1為例。操作中涉及到AT-Link的離線下載模式,詳細描述可以參考ICP使用文檔及AT-Link使用文檔。
方案商和終端用戶代碼分別燒錄
方案商先燒錄SLIB代碼到MCU,然后終端用戶再燒錄應用代碼到MCU,步驟如下:(1)方法A:方案商將編譯完成的工程中SLIB部分的代碼通過ICP截取保存成BIN或者HEX檔:先將整個工程下載到MCU(此時不配置SLIB及FAP等信息),然后通過存儲器讀取功能讀取對應SLIB部分代碼(0x08001000~0x08002FFF),再通過ICP軟件操作文件-存儲器數據另存為將其保存為BIN或者HEX,例程中BIN檔命名為slib.bin,如下圖。圖42. 保存SLIB代碼方法B:方案商將編譯完成的工程直接產生bin格式的文件,取其中SLIB區(qū)域對應的一段,例如在KEIL工程中,user選項中添加fromelf.exe --bin --output .\Listings\@L.bin !L,生成對應固件的bin檔,將對應的SLIB段文件添加后綴名.bin格式,本例中改為ER_SLIB_INSTRUCTION.bin和ER_SLIB_READ_ONLY.bin,對應的就是0x08002000地址段的SLIB-INSTRUCTION文件和0x08001000地址段的SLIB-READ-ONLY文件,如下圖圖43. 生成SLIB代碼部分bin文件(2) 將bin通過ICP工具,在線燒錄到MCU,如下圖圖44. ICP在線燒錄MCU(3) 或者通過ICP工具配置成離線項目工程保存到AT-Link,然后經過AT-Link離線燒錄到MCU,保存離線項目工程如下圖。圖45. AT-Link離線燒錄到MCU(4) 經過步驟2或者步驟3,終端用戶拿到燒錄好SLIB部分的MCU,此時SLIB狀態(tài)會顯示為已啟用,終端用戶通過在線燒錄或者離線燒錄應用代碼到MCU完成整個過程,在線燒錄如下圖。圖46. 終端用戶燒錄代碼到MCU
方案商和終端用戶代碼合并燒錄
方案商的SLIB代碼和終端用戶的應用代碼整合到一個離線項目工程中,通過AT-Link離線燒錄一次下載到MCU,步驟如下:(1) 方案商將編譯完成的工程按照上一章節(jié)所述方法處理,得到SLIB部分的BIN檔。(2) 方案商通過ICP制作離線項目工程并保存到PC,可以根據最終需求配置各種參數,比如限制下載次數、項目文件綁定AT-Link、下載完成后開啟FAP等,保存離線項目工程如下圖注意:離線項目工程本身已經經過加密,為進一步提升安全性,方案商還可以將slib.bin制作成加密的slib.benc文件再添加到離線項目工程中,但此時的離線項目工程只能在對應匹配加密秘鑰的AT-Link上才能使用圖47. 制作離線項目工程(3) 終端用戶拿到該離線項目工程,用ICP打開項目文件,通過添加文件功能,可以添加應用代碼部分到該離線項目工程,然后再保存到PC或者直接存儲到AT-Link,通過執(zhí)行離線下載完成操作,項目文件添加方法如下圖。注意:為防止代碼泄露被破解等風險,離線項目工程添加代碼文件時其余配置都不可更改,所以需要方案商預先將最終配置設置好圖48. 添加項目文件
-
mcu
+關注
關注
146文章
17317瀏覽量
352635 -
控制器
+關注
關注
112文章
16445瀏覽量
179445 -
AT32
+關注
關注
1文章
118瀏覽量
2164
發(fā)布評論請先 登錄
相關推薦
評論