入門:從芯片配置到固件簽名驗(yàn)證實(shí)戰(zhàn))
1. 從一顆小芯片說起為什么安全引導(dǎo)值得單獨(dú)寫一篇筆記第一次接觸ATECC608A這顆芯片是在一個(gè)做物聯(lián)網(wǎng)終端的朋友那里。他當(dāng)時(shí)遇到一個(gè)很實(shí)際的問題設(shè)備出廠后固件被人從外部存儲(chǔ)里直接讀出來改了幾個(gè)字節(jié)再寫回去設(shè)備照樣能跑起來但行為已經(jīng)完全不是原來的邏輯了。這種場(chǎng)景在嵌入式圈子里其實(shí)并不少見尤其是那些部署在無人值守環(huán)境里的設(shè)備物理接觸幾乎不可避免。ATECC608A是Microchip推出的一顆安全協(xié)處理器屬于CryptoAuthentication系列。它內(nèi)部集成了密鑰存儲(chǔ)、硬件加密加速、真隨機(jī)數(shù)發(fā)生器以及一套基于橢圓曲線的簽名與驗(yàn)證機(jī)制。和主控MCU配合使用時(shí)它可以承擔(dān)起安全引導(dǎo)鏈條中最關(guān)鍵的那一環(huán)——驗(yàn)證固件是否被篡改。這篇筆記要聊的就是圍繞ATECC608A搭建一套安全引導(dǎo)入門用例的完整過程。所謂安全引導(dǎo)簡(jiǎn)單說就是設(shè)備上電后在把控制權(quán)交給應(yīng)用固件之前先驗(yàn)證固件的完整性和來源合法性。驗(yàn)證通過就繼續(xù)啟動(dòng)驗(yàn)證失敗就停在引導(dǎo)階段或者進(jìn)入恢復(fù)模式。ATECC608A在這里扮演的角色是那個(gè)“只認(rèn)簽名不認(rèn)人”的守門人。適合讀這篇內(nèi)容的人大概有三類一是正在做物聯(lián)網(wǎng)終端安全方案選型的嵌入式工程師二是已經(jīng)拿到ATECC608A樣品、但對(duì)著數(shù)據(jù)手冊(cè)不知道從哪下手的開發(fā)者三是對(duì)安全引導(dǎo)這個(gè)概念有耳聞、想找一個(gè)具體芯片來落地理解的愛好者。不管你是哪一類這篇筆記都會(huì)從芯片的基本能力講起一路走到可以實(shí)際跑起來的驗(yàn)證流程中間會(huì)穿插我在調(diào)試過程中踩過的坑和總結(jié)出來的經(jīng)驗(yàn)。需要提前說明的是安全引導(dǎo)本身是一個(gè)系統(tǒng)工程涉及密鑰管理、簽名算法、存儲(chǔ)布局、啟動(dòng)流程等多個(gè)環(huán)節(jié)。這篇筆記聚焦在ATECC608A這顆芯片上把它在安全引導(dǎo)中的典型用法講清楚不會(huì)過度展開到整個(gè)安全體系的頂層設(shè)計(jì)。但我會(huì)在關(guān)鍵節(jié)點(diǎn)上解釋為什么這樣設(shè)計(jì)以及如果換一種做法會(huì)帶來什么問題。2. ATECC608A到底能做什么核心能力與安全引導(dǎo)的契合點(diǎn)2.1 芯片內(nèi)部有什么從密鑰存儲(chǔ)到簽名驗(yàn)證ATECC608A的內(nèi)部結(jié)構(gòu)可以理解成一個(gè)專門為密碼學(xué)操作設(shè)計(jì)的小型保險(xiǎn)箱。它有幾個(gè)關(guān)鍵組成部分一是密鑰存儲(chǔ)區(qū)支持多個(gè)槽位每個(gè)槽位可以存放私鑰、公鑰或者數(shù)據(jù)二是硬件加密引擎支持ECC橢圓曲線密碼學(xué)的簽名、驗(yàn)證、密鑰協(xié)商等操作三是SHA-256哈希計(jì)算單元四是一個(gè)真隨機(jī)數(shù)發(fā)生器用于生成密鑰和隨機(jī)挑戰(zhàn)。在安全引導(dǎo)場(chǎng)景里最核心的能力是ECC簽名驗(yàn)證。具體來說固件在發(fā)布前由開發(fā)者的私鑰對(duì)固件鏡像的哈希值進(jìn)行簽名簽名結(jié)果和固件一起打包。設(shè)備啟動(dòng)時(shí)引導(dǎo)程序先計(jì)算固件的哈希值然后調(diào)用ATECC608A用對(duì)應(yīng)的公鑰去驗(yàn)證簽名是否匹配。如果匹配說明固件沒有被篡改且確實(shí)來自持有私鑰的一方。這里有一個(gè)設(shè)計(jì)上的關(guān)鍵點(diǎn)私鑰永遠(yuǎn)不需要離開ATECC608A的存儲(chǔ)區(qū)。簽名操作可以在芯片內(nèi)部完成外部只能拿到簽名結(jié)果拿不到私鑰本身。這就避免了私鑰在主機(jī)端被提取的風(fēng)險(xiǎn)。對(duì)于安全引導(dǎo)來說這意味著即使設(shè)備的引導(dǎo)程序被逆向攻擊者也無法偽造合法的固件簽名。2.2 為什么選ECC而不是RSA資源與效率的權(quán)衡在嵌入式安全領(lǐng)域ECC和RSA是兩條主要的技術(shù)路線。ATECC608A選擇ECC背后有很實(shí)際的考量。RSA的安全性依賴于大數(shù)分解的困難性要達(dá)到等效安全強(qiáng)度密鑰長(zhǎng)度需要很長(zhǎng)。比如2048位的RSA密鑰安全強(qiáng)度大致相當(dāng)于224位的ECC密鑰。密鑰越長(zhǎng)存儲(chǔ)空間、計(jì)算時(shí)間和功耗都會(huì)上去。對(duì)于資源受限的嵌入式設(shè)備來說ECC的優(yōu)勢(shì)很明顯。ATECC608A支持的ECC密鑰長(zhǎng)度是256位簽名和驗(yàn)證操作的耗時(shí)在毫秒級(jí)別功耗也控制在很低的水平。更重要的是芯片內(nèi)部只需要存儲(chǔ)256位的私鑰占用的存儲(chǔ)空間很小這對(duì)于槽位有限的密鑰存儲(chǔ)區(qū)來說很關(guān)鍵。從安全引導(dǎo)的角度看ECC的簽名長(zhǎng)度也比RSA短很多。256位ECC的簽名大約是64字節(jié)而2048位RSA的簽名是256字節(jié)。固件鏡像的簽名數(shù)據(jù)需要和固件一起存儲(chǔ)簽名越短占用的存儲(chǔ)空間越小傳輸和校驗(yàn)的效率也越高。2.3 安全引導(dǎo)中的信任錨ATECC608A的位置安全引導(dǎo)的核心是建立一條信任鏈。信任鏈的起點(diǎn)是一個(gè)不可篡改的信任錨通常是一段固化在芯片內(nèi)部的代碼或者一個(gè)硬件安全模塊。ATECC608A在信任鏈中的位置就是那個(gè)存儲(chǔ)根公鑰的信任錨。具體來說開發(fā)者在生產(chǎn)階段把根公鑰寫入ATECC608A的某個(gè)槽位并配置該槽位為只讀或者需要特定權(quán)限才能修改。設(shè)備啟動(dòng)時(shí)引導(dǎo)程序從ATECC608A讀取這個(gè)公鑰用它來驗(yàn)證下一級(jí)固件的簽名。下一級(jí)固件里可能又包含了對(duì)更上層固件的驗(yàn)證邏輯這樣一層一層往上驗(yàn)證就形成了完整的信任鏈。這種設(shè)計(jì)的巧妙之處在于根公鑰被鎖定在硬件里軟件層面的攻擊很難篡改它。即使攻擊者能夠修改外部存儲(chǔ)中的固件也無法讓設(shè)備接受一個(gè)用錯(cuò)誤私鑰簽名的固件因?yàn)轵?yàn)證用的公鑰是硬件里那個(gè)改不掉的。注意根公鑰的寫入和鎖定通常是一次性操作配置錯(cuò)誤會(huì)導(dǎo)致芯片無法再次修改。在生產(chǎn)階段一定要先在小批量上驗(yàn)證流程確認(rèn)無誤后再批量操作。3. 動(dòng)手之前的準(zhǔn)備硬件、軟件與密鑰規(guī)劃3.1 硬件選型與連接方式ATECC608A的封裝形式有好幾種常見的是8引腳SOIC和UDFN。對(duì)于入門用例來說最方便的是用現(xiàn)成的評(píng)估板或者 breakout 模塊。這類模塊通常已經(jīng)把芯片的I2C引腳引出來供電和電平轉(zhuǎn)換也做好了可以直接和常見的開發(fā)板連接。我用的是一塊基于STM32的開發(fā)板作為主控通過I2C總線和ATECC608A通信。接線很簡(jiǎn)單VCC接3.3VGND接地SDA和SCL分別接主控的I2C引腳另外還有一根引腳用于單線模式或者GPIO控制入門階段可以先不接。需要注意的是ATECC608A的I2C地址是固定的默認(rèn)是0xC07位地址總線上如果有其他同地址的設(shè)備會(huì)沖突。供電方面ATECC608A的工作電壓范圍是2.0V到5.5V但I(xiàn)2C電平需要和主控匹配。如果主控是3.3V系統(tǒng)直接連就行如果是5V系統(tǒng)需要加電平轉(zhuǎn)換。我在調(diào)試時(shí)遇到過因?yàn)殡娖讲黄ヅ鋵?dǎo)致通信不穩(wěn)定的情況后來加了電平轉(zhuǎn)換芯片就正常了。3.2 軟件工具鏈從驅(qū)動(dòng)庫到配置工具M(jìn)icrochip為ATECC608A提供了比較完整的軟件支持。最基礎(chǔ)的是CryptoAuthLib這是一個(gè)開源的C語言庫封裝了芯片的底層通信協(xié)議和常用操作。它支持多種平臺(tái)包括裸機(jī)、Linux、RTOS等移植起來不算復(fù)雜。除了驅(qū)動(dòng)庫還有一個(gè)叫Trust Platform Design Suite的工具用于生成配置文件和密鑰。這個(gè)工具可以幫你在不寫代碼的情況下完成芯片的配置生成一個(gè)配置包然后通過驅(qū)動(dòng)庫寫入芯片。對(duì)于入門來說這個(gè)工具能省去很多手動(dòng)配置寄存器的麻煩。我在實(shí)際使用中的體會(huì)是CryptoAuthLib的文檔雖然不算特別詳細(xì)但示例代碼比較全。建議先把庫里的示例跑通理解基本的讀寫流程再根據(jù)自己的需求修改。另外庫的版本更新比較頻繁不同版本之間的API可能有變化建議鎖定一個(gè)穩(wěn)定版本不要盲目追新。3.3 密鑰規(guī)劃槽位分配與權(quán)限設(shè)置ATECC608A有16個(gè)密鑰槽位每個(gè)槽位可以獨(dú)立配置讀寫權(quán)限和用途。在安全引導(dǎo)場(chǎng)景里至少需要規(guī)劃兩個(gè)槽位一個(gè)用于存儲(chǔ)根公鑰另一個(gè)用于存儲(chǔ)固件簽名驗(yàn)證用的公鑰。如果還需要支持密鑰輪換或者多級(jí)信任鏈可能需要更多槽位。槽位的權(quán)限配置是這一步的關(guān)鍵。根公鑰槽位應(yīng)該配置為只讀并且禁止外部讀取明文。驗(yàn)證用的公鑰槽位可以配置為可讀因?yàn)楣€本身不需要保密。私鑰槽位則應(yīng)該配置為不可讀只能用于內(nèi)部簽名操作。配置一旦寫入并鎖定就無法再修改。所以在規(guī)劃階段一定要想清楚每個(gè)槽位的用途和權(quán)限。我建議在紙上畫一個(gè)槽位分配表把每個(gè)槽位的編號(hào)、用途、讀寫權(quán)限、鎖定狀態(tài)都列清楚避免配置時(shí)搞混。槽位編號(hào)用途讀權(quán)限寫權(quán)限鎖定狀態(tài)0根公鑰存儲(chǔ)允許禁止已鎖定1固件驗(yàn)證公鑰允許禁止已鎖定2設(shè)備私鑰禁止禁止已鎖定3數(shù)據(jù)存儲(chǔ)允許允許未鎖定提示槽位0通常有特殊用途部分型號(hào)默認(rèn)用于存儲(chǔ)序列號(hào)或配置數(shù)據(jù)。在規(guī)劃時(shí)先查一下數(shù)據(jù)手冊(cè)確認(rèn)哪些槽位有特殊限制。4. 安全引導(dǎo)用例的完整實(shí)現(xiàn)過程4.1 第一步芯片初始化與配置寫入拿到全新的ATECC608A芯片后第一步是初始化。芯片出廠時(shí)處于未配置狀態(tài)需要先執(zhí)行喚醒、檢查狀態(tài)、寫入配置區(qū)等操作。CryptoAuthLib里提供了atcab_init和atcab_config_zone_write等函數(shù)來完成這些步驟。配置區(qū)的寫入需要格外小心。配置區(qū)包含了芯片的各種參數(shù)比如I2C地址、睡眠模式、看門狗設(shè)置等。如果寫錯(cuò)了芯片可能無法正常通信。我的做法是先用Trust Platform Design Suite生成一個(gè)配置文件然后在代碼里讀取這個(gè)文件并寫入芯片。寫入完成后一定要執(zhí)行鎖定操作否則配置區(qū)可以被反復(fù)修改安全性無從談起。鎖定配置區(qū)是一個(gè)不可逆的操作。執(zhí)行atcab_lock_config_zone之后配置區(qū)就變成只讀了。在鎖定之前建議先讀取配置區(qū)的內(nèi)容和預(yù)期值逐字節(jié)比對(duì)確認(rèn)無誤后再鎖定。我就遇到過因?yàn)榕渲梦募姹静粚?duì)導(dǎo)致鎖定后芯片行為異常的情況最后只能換芯片。4.2 第二步密鑰生成與公鑰導(dǎo)出配置鎖定后下一步是生成密鑰對(duì)。ATECC608A支持在芯片內(nèi)部生成ECC密鑰對(duì)私鑰永遠(yuǎn)不出芯片公鑰可以導(dǎo)出。生成密鑰的命令是atcab_genkey傳入槽位編號(hào)芯片會(huì)生成一個(gè)新的密鑰對(duì)并存儲(chǔ)在該槽位。公鑰導(dǎo)出后需要保存到主機(jī)端用于后續(xù)的簽名驗(yàn)證。導(dǎo)出的公鑰是一個(gè)64字節(jié)的數(shù)據(jù)包含X和Y坐標(biāo)各32字節(jié)。在實(shí)際使用中通常還需要對(duì)公鑰進(jìn)行哈?;蛘呔幋a以便嵌入到引導(dǎo)程序或者證書中。這里有一個(gè)細(xì)節(jié)需要注意ATECC608A生成的密鑰對(duì)是基于P-256曲線的這是NIST定義的一條標(biāo)準(zhǔn)曲線。在驗(yàn)證簽名時(shí)主機(jī)端也需要使用相同的曲線參數(shù)。如果主機(jī)端用的是其他曲線驗(yàn)證會(huì)失敗。我在第一次調(diào)試時(shí)就是因?yàn)橹鳈C(jī)端默認(rèn)用了另一條曲線導(dǎo)致驗(yàn)證一直不通過排查了很久才發(fā)現(xiàn)是曲線參數(shù)不匹配。4.3 第三步固件簽名與簽名數(shù)據(jù)打包固件簽名是在發(fā)布階段完成的。流程是先計(jì)算固件鏡像的SHA-256哈希值然后調(diào)用ATECC608A用私鑰對(duì)這個(gè)哈希值進(jìn)行簽名。簽名結(jié)果是一個(gè)64字節(jié)的數(shù)據(jù)需要和固件一起打包。打包的格式可以自己定義常見的方式是在固件頭部加一個(gè)簽名區(qū)包含簽名數(shù)據(jù)、公鑰標(biāo)識(shí)、固件長(zhǎng)度等信息。引導(dǎo)程序在啟動(dòng)時(shí)先讀取這個(gè)頭部提取簽名和固件長(zhǎng)度然后計(jì)算固件主體的哈希值最后調(diào)用ATECC608A驗(yàn)證簽名。這里有一個(gè)容易忽略的點(diǎn)哈希計(jì)算的范圍必須和簽名時(shí)完全一致。如果簽名時(shí)是對(duì)整個(gè)固件鏡像計(jì)算哈希驗(yàn)證時(shí)也必須對(duì)整個(gè)鏡像計(jì)算不能只算一部分。我在實(shí)際項(xiàng)目中遇到過因?yàn)楹灻万?yàn)證的哈希范圍不一致導(dǎo)致驗(yàn)證失敗的情況。后來在代碼里加了一個(gè)宏定義把哈希范圍固定下來兩邊都用同一個(gè)宏避免了人為錯(cuò)誤。4.4 第四步引導(dǎo)程序中的驗(yàn)證流程實(shí)現(xiàn)引導(dǎo)程序的驗(yàn)證流程是整個(gè)安全引導(dǎo)的核心。大致步驟如下設(shè)備上電引導(dǎo)程序首先初始化ATECC608A檢查通信是否正常。從外部存儲(chǔ)讀取固件頭部提取簽名數(shù)據(jù)和固件長(zhǎng)度。計(jì)算固件主體的SHA-256哈希值。調(diào)用ATECC608A的驗(yàn)證命令傳入公鑰槽位、哈希值和簽名數(shù)據(jù)。根據(jù)驗(yàn)證結(jié)果決定是否跳轉(zhuǎn)到應(yīng)用固件。驗(yàn)證命令是atcab_verify它需要幾個(gè)參數(shù)公鑰槽位編號(hào)、待驗(yàn)證的哈希值、簽名數(shù)據(jù)、以及一個(gè)輸出參數(shù)用于返回驗(yàn)證結(jié)果。如果驗(yàn)證通過芯片會(huì)返回一個(gè)成功標(biāo)志如果失敗返回錯(cuò)誤碼。在實(shí)際實(shí)現(xiàn)中我建議把驗(yàn)證流程封裝成一個(gè)獨(dú)立的函數(shù)輸入是固件存儲(chǔ)地址和長(zhǎng)度輸出是驗(yàn)證結(jié)果。這樣便于在不同的啟動(dòng)階段復(fù)用也方便單獨(dú)測(cè)試。另外驗(yàn)證失敗后的處理策略也需要提前規(guī)劃是停在引導(dǎo)階段等待恢復(fù)還是進(jìn)入一個(gè)受限的恢復(fù)模式取決于設(shè)備的使用場(chǎng)景。注意驗(yàn)證操作本身需要一定的時(shí)間具體取決于芯片的時(shí)鐘頻率和I2C速度。在低功耗場(chǎng)景下需要評(píng)估驗(yàn)證耗時(shí)對(duì)啟動(dòng)時(shí)間的影響。5. 調(diào)試過程中遇到的典型問題與排查方法5.1 通信失敗I2C層面的常見故障ATECC608A的I2C通信是最容易出問題的地方。常見現(xiàn)象包括無法喚醒芯片、讀寫超時(shí)、返回?cái)?shù)據(jù)全為0或全為0xFF。排查時(shí)可以從以下幾個(gè)方面入手。首先檢查硬件連接。用示波器或者邏輯分析儀抓一下SDA和SCL的波形確認(rèn)時(shí)鐘頻率是否在芯片支持的范圍內(nèi)。ATECC608A支持標(biāo)準(zhǔn)模式100kHz和快速模式400kHz但實(shí)際使用時(shí)建議先用100kHz調(diào)試穩(wěn)定后再提高速度。我在調(diào)試時(shí)遇到過因?yàn)樯侠娮枳柚挡缓线m導(dǎo)致波形上升沿太緩的情況換了小一點(diǎn)的電阻就正常了。其次檢查I2C地址。ATECC608A的默認(rèn)地址是0xC0但有些模塊可能通過引腳配置改變了地址。用I2C掃描工具掃一下總線確認(rèn)設(shè)備地址是否正確。如果總線上有多個(gè)設(shè)備還要注意地址沖突的問題。最后檢查電源。ATECC608A在喚醒和加密操作時(shí)會(huì)有瞬態(tài)電流如果電源去耦不充分可能導(dǎo)致電壓跌落通信中斷。建議在VCC引腳附近加一個(gè)0.1uF的陶瓷電容必要時(shí)再加一個(gè)1uF的鉭電容。5.2 驗(yàn)證失敗簽名與哈希的匹配問題驗(yàn)證失敗是安全引導(dǎo)調(diào)試中最常見的問題之一??赡艿脑蛴泻芏嗯挪闀r(shí)可以按照以下順序進(jìn)行。先確認(rèn)公鑰是否正確。從ATECC608A導(dǎo)出的公鑰和主機(jī)端用于驗(yàn)證的公鑰必須是同一對(duì)密鑰。如果公鑰不匹配驗(yàn)證必然失敗??梢栽谥鳈C(jī)端用同樣的公鑰對(duì)簽名進(jìn)行驗(yàn)證如果主機(jī)端驗(yàn)證通過而芯片端失敗說明問題出在芯片端如果兩端都失敗說明簽名或者哈希有問題。再確認(rèn)哈希計(jì)算范圍是否一致。簽名時(shí)對(duì)哪些數(shù)據(jù)計(jì)算了哈希驗(yàn)證時(shí)也必須對(duì)同樣的數(shù)據(jù)計(jì)算哈希。任何字節(jié)的差異都會(huì)導(dǎo)致哈希值不同進(jìn)而導(dǎo)致驗(yàn)證失敗。建議在簽名和驗(yàn)證的代碼里使用同一個(gè)函數(shù)來計(jì)算哈希避免手動(dòng)實(shí)現(xiàn)帶來的差異。最后確認(rèn)簽名數(shù)據(jù)的格式。ATECC608A的簽名結(jié)果是64字節(jié)包含R和S兩個(gè)分量各32字節(jié)。有些庫或者工具會(huì)對(duì)簽名進(jìn)行DER編碼編碼后的長(zhǎng)度會(huì)變化。如果簽名數(shù)據(jù)在傳輸或存儲(chǔ)過程中被編碼或解碼需要確保驗(yàn)證時(shí)傳入的是原始格式。5.3 配置鎖定后的異常不可逆操作的后果配置區(qū)鎖定后如果發(fā)現(xiàn)芯片行為異?;旧蠜]有挽回的余地。我遇到過兩種情況一種是鎖定后I2C地址變了導(dǎo)致無法通信另一種是鎖定后某個(gè)槽位的權(quán)限配置錯(cuò)誤導(dǎo)致密鑰無法使用。避免這類問題的唯一方法是在鎖定前充分測(cè)試。具體來說可以在未鎖定狀態(tài)下把所有功能跑一遍包括密鑰生成、簽名、驗(yàn)證、讀寫槽位等。確認(rèn)所有操作都符合預(yù)期后再執(zhí)行鎖定。另外建議保留幾顆未鎖定的芯片作為備用萬一鎖定后發(fā)現(xiàn)問題還有回旋的余地。如果確實(shí)遇到了鎖定后異常的情況可以嘗試用單線模式或者GPIO喚醒的方式重新建立通信。有些異常是因?yàn)樾酒M(jìn)入了低功耗模式或者睡眠模式通過特定的喚醒序列可以恢復(fù)。但如果配置區(qū)本身寫錯(cuò)了那就只能更換芯片了。5.4 常見問題速查表現(xiàn)象可能原因排查方法解決措施無法喚醒芯片電源不穩(wěn)、I2C地址錯(cuò)誤檢查供電、掃描I2C總線加去耦電容、確認(rèn)地址讀寫超時(shí)時(shí)鐘頻率過高、上拉電阻不合適降低時(shí)鐘頻率、檢查波形調(diào)整上拉電阻、降速驗(yàn)證失敗公鑰不匹配、哈希范圍不一致對(duì)比公鑰、檢查哈希計(jì)算范圍統(tǒng)一公鑰和哈希范圍簽名失敗私鑰槽位權(quán)限錯(cuò)誤、密鑰未生成檢查槽位配置、確認(rèn)密鑰存在重新配置槽位、生成密鑰配置鎖定后異常配置參數(shù)錯(cuò)誤、鎖定操作不可逆鎖定前充分測(cè)試更換芯片、重新配置6. 從入門用例到實(shí)際部署還需要考慮什么6.1 密鑰的生命周期管理入門用例里密鑰的生成、使用和存儲(chǔ)都比較簡(jiǎn)單。但在實(shí)際部署中密鑰的生命周期管理是一個(gè)需要認(rèn)真對(duì)待的問題。密鑰從哪里來、怎么分發(fā)到設(shè)備、怎么更新、怎么撤銷這些環(huán)節(jié)都需要有明確的流程。對(duì)于ATECC608A來說私鑰可以在芯片內(nèi)部生成不需要外部注入這簡(jiǎn)化了密鑰分發(fā)的環(huán)節(jié)。但公鑰的分發(fā)和信任建立仍然需要一套機(jī)制。常見的方式是使用證書鏈根證書的公鑰存儲(chǔ)在ATECC608A里設(shè)備證書由根證書簽名固件簽名使用設(shè)備證書對(duì)應(yīng)的私鑰。這樣在驗(yàn)證固件時(shí)可以先驗(yàn)證設(shè)備證書再驗(yàn)證固件簽名形成完整的信任鏈。密鑰更新是一個(gè)更復(fù)雜的問題。ATECC608A的槽位一旦鎖定密鑰就無法直接替換。如果需要支持密鑰更新需要在規(guī)劃階段預(yù)留可寫的槽位或者設(shè)計(jì)一套密鑰派生機(jī)制用根密鑰派生出不同版本的子密鑰。6.2 固件更新的安全引導(dǎo)銜接安全引導(dǎo)不僅要在啟動(dòng)時(shí)驗(yàn)證固件在固件更新時(shí)也需要驗(yàn)證新固件的合法性。否則攻擊者可以通過更新流程植入惡意固件。固件更新的驗(yàn)證流程和啟動(dòng)驗(yàn)證類似但多了一個(gè)寫入外部存儲(chǔ)的步驟。典型的流程是設(shè)備接收到新固件后先驗(yàn)證簽名驗(yàn)證通過后再寫入外部存儲(chǔ)然后重啟進(jìn)入新的固件。如果驗(yàn)證失敗拒絕寫入并保持當(dāng)前固件運(yùn)行。這里需要注意的是寫入過程中如果斷電可能導(dǎo)致固件不完整。所以通常需要設(shè)計(jì)一個(gè)雙分區(qū)或者備份機(jī)制確保更新失敗后設(shè)備仍然可以啟動(dòng)。ATECC608A在固件更新中的角色仍然是提供簽名驗(yàn)證服務(wù)。由于驗(yàn)證操作在芯片內(nèi)部完成即使更新程序被篡改也無法繞過簽名驗(yàn)證。這為固件更新提供了一層硬件級(jí)的安全保障。6.3 性能與功耗的平衡ATECC608A的加密操作會(huì)消耗一定的功耗和時(shí)間。在電池供電的設(shè)備中需要在安全性和功耗之間做平衡。一個(gè)常見的做法是只在啟動(dòng)時(shí)驗(yàn)證一次固件運(yùn)行期間不再重復(fù)驗(yàn)證。這樣可以減少加密操作的次數(shù)降低平均功耗。另一個(gè)優(yōu)化點(diǎn)是驗(yàn)證的時(shí)機(jī)。如果設(shè)備支持低功耗休眠可以在喚醒后先不驗(yàn)證等到需要執(zhí)行關(guān)鍵操作時(shí)再驗(yàn)證。但這樣做會(huì)引入一個(gè)風(fēng)險(xiǎn)窗口在驗(yàn)證之前設(shè)備可能已經(jīng)執(zhí)行了部分未驗(yàn)證的代碼。所以這種優(yōu)化需要謹(jǐn)慎評(píng)估確保不會(huì)削弱安全引導(dǎo)的效果。從實(shí)測(cè)數(shù)據(jù)來看ATECC608A完成一次ECC簽名驗(yàn)證的耗時(shí)在幾十毫秒左右具體取決于I2C速度和芯片時(shí)鐘。功耗方面一次驗(yàn)證操作的能耗在毫安時(shí)級(jí)別對(duì)于大多數(shù)物聯(lián)網(wǎng)設(shè)備來說是可以接受的。6.4 安全引導(dǎo)的邊界與局限安全引導(dǎo)能解決固件完整性和來源合法性的問題但它不是萬能的。它無法防止物理層面的攻擊比如探針讀取芯片內(nèi)部數(shù)據(jù)、故障注入改變驗(yàn)證結(jié)果等。ATECC608A本身有一定的防篡改設(shè)計(jì)比如主動(dòng)屏蔽層、加密存儲(chǔ)等但這些措施的效果取決于具體的攻擊手段和投入成本。另外安全引導(dǎo)依賴于引導(dǎo)程序本身的正確性。如果引導(dǎo)程序存在漏洞攻擊者可能通過漏洞繞過驗(yàn)證。所以引導(dǎo)程序的代碼需要經(jīng)過嚴(yán)格的安全審計(jì)盡量減少攻擊面。在實(shí)際項(xiàng)目中我通常會(huì)把引導(dǎo)程序做得盡可能小只保留必要的驗(yàn)證和跳轉(zhuǎn)邏輯其他功能都放到應(yīng)用固件里。從整體安全體系來看安全引導(dǎo)是其中一環(huán)還需要配合安全啟動(dòng)、安全通信、安全存儲(chǔ)等其他機(jī)制才能形成完整的防護(hù)。ATECC608A作為一顆安全協(xié)處理器可以在多個(gè)環(huán)節(jié)發(fā)揮作用但具體怎么用取決于整體的安全需求和威脅模型。我個(gè)人在實(shí)際操作中的體會(huì)是安全引導(dǎo)的調(diào)試過程比較考驗(yàn)?zāi)托挠绕涫巧婕暗矫荑€和簽名的環(huán)節(jié)任何一個(gè)細(xì)節(jié)出錯(cuò)都會(huì)導(dǎo)致驗(yàn)證失敗。建議在每一步都做好記錄把公鑰、哈希值、簽名數(shù)據(jù)都保存下來方便對(duì)比排查。另外不要等到產(chǎn)品快發(fā)布時(shí)才引入安全引導(dǎo)最好在項(xiàng)目初期就把安全需求考慮進(jìn)去這樣在硬件選型和軟件架構(gòu)上都有更大的調(diào)整空間。