在韌體更新中加密密鑰
我在小型設備(Cortex-M0/M3)上有一個引導載入程序。我想使用引導載入程序發布可以安裝在設備上的加密韌體更新。加密的重點是防止複制韌體或安裝未經授權的軟體。該器件提供了一些回讀保護手段。
我在引導載入程序(k1、k2、k3…)中儲存了一組 256 位密鑰。該組密鑰可能因設備而異(許可證),並且每個密鑰都與某種功能相關聯。現在我想定義引導載入程序需要哪些密鑰來解密韌體。例如:k1 和 k2 或 k2 和 k3。
我使用隨機密鑰 (kr) 和隨機 IV 使用 AES/GCM 加密和驗證韌體。對於可用於解密韌體的每個密鑰組合,我將儲存加密的隨機密鑰 kr,該密鑰由通過異或所需密鑰建構的密鑰加密。
以上面的例子為例:如果我想在所有知道 k1 和 k2 或 k2 和 k3 的設備上安裝韌體,我會將 E(k1 xor k2, kr) 和 E(k2 xor k3, kr) 儲存為沿加密韌體的純文字。
現在,我有三個問題:上面的方法聽起來合理嗎?我可以使用 AES/ECB 作為 E 來加密組合密鑰嗎?我可以將 AES/CTR 與韌體的 AES/GCM 加密中的相同 IV 一起使用嗎?
您的方法似乎有很多不必要的複雜性和限制。例如,您必須提前確定特徵和鍵之間的映射。以下是一些更通用的更簡單的方法:
**每個引導載入程序一個密鑰:**我們稱之為客戶端密鑰。然後要將韌體發送到特定的引導載入程序,您可以使用該引導載入程序的客戶端密鑰對其進行加密/驗證。
**每個引導載入程序一個密鑰,每個版本一個密鑰:**您可以通過避免使用不同的客戶端密鑰浪費性地重新加密相同的韌體來節省計算/頻寬/儲存。使用這種方法,您可以為每個韌體更新生成一個發布密鑰,並使用發布密鑰加密/驗證韌體,然後使用每個引導載入程序的客戶端密鑰僅加密/驗證發布密鑰(當然,僅適用於您希望允許的引導載入程序安裝此更新)。
**一個主密鑰:**您還可以使用一個主密鑰並為每個引導載入程序提供一個唯一 ID。然後,在發布韌體更新時,您可以包含列出允許安裝它的引導載入程序 ID 的元數據。該元數據將與韌體本身一起使用主密鑰進行加密/驗證。然後引導載入程序的受信任部分在允許寫入之前檢查其 ID 是否在列表中。請注意,使用這種方法,如果有人設法通過逆向工程讀取主密鑰,他們可以輕鬆地為所有引導載入程序批量生產更新,這是每個引導載入程序具有一個密鑰的方法中不存在的非功能。
要將基於“功能”的方法映射到此,您可以考慮將引導載入程序中的不同功能集映射到不同的 ID。因此,ID 不必唯一標識每個設備,而只需標識每個功能集(如果需要)。
**一個主公鑰:**與上述方法類似,但使用公鑰加密對韌體更新進行簽名。單個設備的中斷將允許攻擊者讀取所有未來的韌體更新,但至少他們將無法生成自製更新。