隨著物聯網(IoT)裝置的廣泛普及——從智慧城市到無線珠寶,物聯網幾乎滲透到日常生活的每一步,對於物聯網類型的嵌入式系統劃定安全優先順序的需求日益迫切。確保安全的啟動過程是保護任何嵌入式系統的首要步驟,也是在應用中預防惡意軟體壁壘的必要部份。讓我們看看其優缺點,並以電子產業中常見的處理器之一——i.MX6為例加以說明。

什麼是安全啟動?

「安全啟動」(secure boot)是指作業系統(OS)在啟動鏡像與程式碼之前必須先根據硬體進行認證,才能使其用於啟動的過程。硬體必須以此方式提前作好準備:它只認證使用受信任的安全憑證所產生的程式碼。總之,它確保開機啟動和OS軟體是預期的製造商版本,而不至於被惡意軟體或惡意的第三方篡改過。

安全啟動適用於任何單一用途的裝置,例如廣泛使用i.MX6處理器(如整合E-Ink顯示控制器的i.MX6 Solo和DuaLite)的電子書閱讀器(e-reader),它們主要用於閱讀電子書,而不是一般的運算。在這種案例中,在開機啟動時鎖定Linux環境是很有幫助的。

諸如Android手機等其它情形可能就有所取捨了,例如,使用安全啟動可能會限制終端用戶執行客製ROM。能夠做到這點也許是一項特色功能,或者可能是根據產品佈局或安全要求的理想功能。基本上,適於使用安全啟動的理想時機在於,當你不希望另一方在你的裝置中載入作業系統或其它啟動載入程式之際。

對於執行Linux的IP相機等更高整合度的系統來說,更多人會建議你使用安全啟動,因為任何惡意開機程式碼或作業系統軟體,都可能把你的裝置變成僵屍網路的一部份。或者可能是從攝影機拍到的畫面被公開上傳到網際網路,或甚至被修改成不包含視訊主人想要的影片片段等資訊。

i.MX6上的安全啟動過程

一旦在i.MX6上建立了開機啟動鏡像,為了利用安全啟動,必須針對為此目的產生的SSL憑證產生一組安全金鑰。

這些金鑰用於產生一組安全指令,然後利用供應商(如飛思卡爾,如今的恩智浦)提供的工具編譯後追加到啟動鏡像中。處理器隨即取得第一階段的啟動載入程式,並採用你的憑證來認證以安全啟動編譯工具產生的憑證資料。

在寫入啟動媒介時,如果啟動鏡像中的金鑰資料符合儲存在處理器安全記憶體中的金鑰資料,將會開始執行安全指令,然後檢查鏡像的密碼雜湊值,確保其與安全指示值相符。如果彼此符合,處理器將會開始載入並執行你的啟動鏡像。

一旦這個過程通過CPU的內部啟動載入程式,你仍然可以從啟動載入程式的程式碼調用安全開機庫。這可讓你載入作業系統鏡像,並以CPU啟動載入程式認證軟體啟動載入程式的相同方式加以認證。

在這個過程結束時,作業系統將在通過驗證的安全環境中完成啟動。你知道這很合理,因為每一階段都對於處理器中儲存的金鑰雜湊值進行認證測試。

一次性可編程設計

從安全角度看這個過程,從SSL憑證所產生的根金鑰(root key)經過雜散後,再以一次性可編程(OTP)設計燒入CPU中。一旦這個金鑰燒入處理器後就不能修改了——理由之一是安全。

啟動鏡像也在此金鑰基礎上簽名,而在此簽名過程所產生的資料將與鏡像結合。處理器利用其金鑰檢查你的鏡像金鑰,如果彼此相符,則會以剛好符合處理器的金鑰檢查你的鏡像。如果仍然相符,就能執行鏡像。這一步驟會將你帶到更上層鏈,從CPU啟動載入程式到正常啟動載入程式,再到作業系統。

當然,這可能是i.MX6特有的情況,實際上還有各種不同類型的安全啟動,例如採用UEFI安全啟動的X86,但為了便於理解,本文重點還是放在i.MX6上。

利用硬體

i.MX6硬體套件包括許多有益於安全啟動的特殊安全機制。用於安全啟動的關鍵部份是燒入金鑰時所使用的一次性熔絲(one-time fuse)。一旦熔斷後就無法再接起來,因此一旦燒入你的金鑰後,其雜湊值就具有永久性了。多個金鑰也可以整合於一個金鑰雜湊值,因此如果受到威脅時就可以廢除一個金鑰。

系統安全性的另一個功能是CPU內部啟動載入程式,這是一段同樣經過安全測試的靜態程式碼。這是一直到作業系統的整條鏈得以保持安全的重要基礎。

此外,i.MX6具有一個硬體密碼演算法加速器。諸如AES雜湊、Triple DES雜湊、SHA1和SHA256等演算法,都能經由i.MX6處理器進行加速,從而大幅提高安全處理的速度。

缺點

最明顯的缺點是必須負責自己的安全性。如果你的金鑰洩露給外界,就會有人利用儲存在處理器中的金鑰為程式碼簽名,因此你必須確保處理過程和硬體的安全。

另外,只為安全啟動目的而配置的處理器,只有在鏡像得到正確簽名後才能啟動。因此,在將雜湊值燒入處理器的過程中,如果發生任何差錯都會導致處理器無法執行程式碼,因為燒入的雜湊值並不相符——因而成為一個無用的處理器。

一旦處理器被設置為安全執行,那就必須載入安全的程式碼。它只允許你從儲存(如SD卡或NAND快閃記憶體)中安全地載入,或以其它方式將軟體載入處理器(USB鏡像載入)中。

因此,硬體和處理器的準備工作一定要保證安全。此外,還必須確保你的啟動載入程式也為此作好充份準備。

如前所述,你的啟動載入程式必須調用處理器上的安全啟動庫,以便認證啟動鏈的下一階段。如果未能正確地編碼啟動載入程式以便正確使用安全庫,那麼你可能無法完全確保作業系統的安全性。

不要掉入虛假的安全感陷阱

需要弄清楚的是,i.MX6的安全啟動並不會鎖定整個系統,而只是鎖定作業系統軟體。因此有人可能編寫一些在作業系統上執行的Linux惡意軟體,如果它們成功載入後,將會危害到整個系統。

i.MX6安全啟動認證

如果要求更完整的安全性,還可以認證檔案系統中的其他部份和程式碼。i.MX6的安全啟動過程原則是特定記憶體塊具有特定的密碼雜湊值和有關的簽名資訊。如此就可以將作業系統的根檔案系統和其它重要檔案載入記憶體中的某個固定位置,同時載入正確的安全指令集。這樣允許你在必要時認證系統的其它部份。

i.MX6安全啟動的重要訣竅

1. 確保啟動過程是安全的 一旦你決定需要走安全啟動路徑,那就必須確保相關過程也能並駕齊驅。在生產環境中洩露了金鑰將功敗垂成。

2. 確保強勁的加密方法 確保所使用的加密方法足夠強勁。使用者很可能建立力度較弱的金鑰,而i.MX6上的安全啟動也支援一些較老舊或如今被視為妥協折衷的組合。因此,確保你的演算法是最新的,能夠滿足目標要求。

3. 檢查你的程式碼 為了實現安全啟動,意味著任何事情,包括啟動載入程式中的其餘程式碼、作業系統和其它軟體都必須在安全啟動的原則下正確編寫,而不能出現安全漏洞。

另外,啟動過程的每一階段在執行前必須檢查下一步。如果沒有做到這點,或者部份做到,那麼能夠稱為過程安全的範圍就會小很多。

4. 認證每個地方 為了實現真正的安全,盡可能地認證你想載入的所有程式碼,並確保遵循針對庫建立的操作方法。

你必須確保整個過程的安全,即如何產生和儲存你的金鑰。安全啟動只能檢查簽名,而任何簽名的鏡像都會被處理器認為是安全的。

因此,確保你所寫入的每一個程式碼獨立部份,都能被調用於處理器的安全啟動庫中,以便繼續認證你的鏡像,因為大多數i.MX6電路板都有多個階段的啟動過程, CPU內部啟動載入程式先是載入SPL,然後SPL接著載入完整的啟動載入程式,以便載入作業系統。每一步都必須經過前一步驟的認證,以便確認是安全的。

5. 確認過程經過有效認證 確保程式碼能真正執行安全啟動至關重要。即使是安全的程式碼也可能跳到記憶體的任何位置繼續執行,因為處理器的工作原理就是這樣的。為了保持安全,實際確保程式碼將會認證下一步程式碼至關重要。

i.MX6最常使用的啟動載入程式是U-Boot,它真正支援在i.MX6上執行安全啟動。它需要進行配置,不過比較簡單些。當有大量的工作已經先行處理好了,你應該就會較少出錯。從頭開始編寫安全性並不是個好辦法,最好是採取一種已知的理想建置方式,並使其符合你的設計需求。

(參考原文:The whys and hows of secure boot,by Nathan Padoin)