在 Keymaster 1 中,所有 Keymaster 金鑰都會以加密方式繫結至裝置 信任根或驗證開機程序金鑰。在 Keymaster 2 和 3 中,所有 金鑰也會繫結至系統映像檔的作業系統和修補程式等級。 這可確保攻擊者在舊檔中發現弱點 版本的系統或 TEE 軟體無法將裝置復原至安全漏洞 版本,並使用以新版本建立的金鑰。此外,當鍵 搭載指定版本和修補程式的裝置 較新的版本或修補程式等級,金鑰會先升級才能使用。 ,且舊版的金鑰已失效。簡單來說,裝置就是 這些金鑰就會「寫」沿著裝置移動 將裝置還原為先前版本後,金鑰就會重新同步 無法使用。
為了支援 Treble 的模組化結構,並破壞 system.img 的繫結 boot.img、Keymaster 4 將金鑰版本繫結模型改為 每個分區的所有修補程式等級這樣您就能更新每個分區 同時仍提供復原保護機制
在 Android 9 中,boot
、system
和 vendor
每個分區都有自己的修補程式等級
- 搭載 Android 驗證開機程序 (AVB) 的裝置可加入所有修補程式等級
以及 vbmeta 中的系統版本
讓系統啟動載入程式能提供給
Keymaster。如果是鏈結分區,則分區的版本資訊
位於鏈結的 vbmeta 中。一般來說,版本資訊必須在
vbmeta struct
包含驗證資料 (雜湊或 雜湊陣列)。 - 在不支援 AVB 的裝置上:
- 驗證開機程序須提供版本的雜湊。 中繼資料提交至系統啟動載入程式,讓系統啟動載入程式可將雜湊提供給 Keymaster。
boot.img
可以繼續將修補程式等級儲存在標頭中system.img
可以繼續以唯讀模式儲存修補程式等級和 OS 版本 屬性vendor.img
會將修補程式等級儲存在唯讀屬性中ro.vendor.build.version.security_patch
。- 系統啟動載入程式可提供雜湊開機程序驗證的所有資料 。
- 在 Android 9 中,請使用下列標記提供
下列分區:
VENDOR_PATCH_LEVEL
:vendor
個分區BOOT_PATCH_LEVEL
:boot
個分區OS_PATCH_LEVEL
和OS_VERSION
:system
個分區。(OS_VERSION
已從以下位置移除:boot.img
標頭。
-
Keymaster 實作應單獨處理所有修補程式等級。索引鍵為
如果所有版本資訊都與某個索引鍵的關聯值相符,即可使用此項目,且
如果發生以下情況,
IKeymaster::upgradeDevice()
會擲回較高的修補程式等級 。
HAL 變更
為了支援版本繫結和版本認證,Android 7.1 新增了
標記 Tag::OS_VERSION
和 Tag::OS_PATCHLEVEL
,以及
configure
和 upgradeKey
方法。版本標記
Keymaster 2+ 實作項目會自動新增至所有新產生的
(或更新) 鍵。除此之外,任何嘗試使用沒有 OS 的金鑰
與目前系統 OS 版本或修補程式等級相符的版本或修補程式等級
這兩個屬性會分別由 ErrorCode::KEY_REQUIRES_UPGRADE
拒絕。
Tag::OS_VERSION
是一個 UINT
值,代表
Android 系統版本的主要、次要和副次要部分,作為 MMmms
MM 是主要版本,mm 代表子版本,s 則是次次要版本
版本。舉例來說,6.1.2 會以 060102 表示。
Tag::OS_PATCHLEVEL
是一個 UINT
值,代表
上次更新系統的年份和月份 (格式為 YYYYMM),其中 YYYY 是
四位數的年份,MM 代表兩位數的月份。例如 2016 年 3 月是
如 201603
升級金鑰
允許金鑰升級至系統的新 OS 版本和修補程式等級
映像檔,Android 7.1 新增了 upgradeKey
方法至 HAL:
Keymaster 3
upgradeKey(vec keyBlobToUpgrade, vec upgradeParams) generates(ErrorCode error, vec upgradedKeyBlob);
Keymaster 2
keymaster_error_t (*upgrade_key)(const struct keymaster2_device* dev, const keymaster_key_blob_t* key_to_upgrade, const keymaster_key_param_set_t* upgrade_params, keymaster_key_blob_t* upgraded_key);
- 「
dev
」是裝置結構 keyBlobToUpgrade
是需要升級的金鑰upgradeParams
是升級金鑰所需的參數。這些 會包含「Tag::APPLICATION_ID
」和Tag::APPLICATION_DATA
,必須使用才能解密金鑰 blob。upgradedKeyBlob
是輸出參數,用來傳回 新的鍵 blob。
如果使用無法剖析的鍵 blob 呼叫 upgradeKey
,或是
否則會傳回 ErrorCode::INVALID_KEY_BLOB
。如果是
呼叫已被呼叫的金鑰,該鍵的修補程式等級大於目前的系統值。
它會傳回 ErrorCode::INVALID_ARGUMENT
。如果以金鑰呼叫
作業系統版本大於目前系統值,而系統值
不為零,則會傳回 ErrorCode::INVALID_ARGUMENT
。OS 版本
允許從非零升級至零的數值。發生錯誤時
與安全的世界通訊,會傳回適當的錯誤值 (例如
ErrorCode::SECURE_HW_ACCESS_DENIED
,
ErrorCode::SECURE_HW_BUSY
)。如果沒有,則會傳回
ErrorCode::OK
並傳回新的鍵 blob
upgradedKeyBlob
。
「keyBlobToUpgrade
」在 upgradeKey
後仍然有效
呼叫,理論上如果裝置降級,可能會再次使用。於
KeyStore 通常會呼叫 deleteKey
keyBlobToUpgrade
blob 在呼叫
upgradeKey
。如果「keyBlobToUpgrade
」含有標記
Tag::ROLLBACK_RESISTANT
,接著upgradedKeyBlob
應該
也應避免復原
安全設定
如要實作版本繫結,Keymaster TA 必須採取 目前的 OS 版本和修補程式等級 (版本資訊),並確保 收到的資訊密切相關 有些人會將 Cloud Storage 視為檔案系統 但實際上不是
如要以安全的方式將版本資訊傳送至 TA,OS_VERSION
欄位 已新增至開機映像檔標頭。開機映像檔版本
就會自動填入這個欄位原始設備製造商 (OEM) 和 Keymaster TA 實作者
必須搭配運作,修改裝置的系統啟動載入程式,以擷取版本
然後將開機映像檔的資訊傳遞至 TA
啟動。這可確保攻擊者不會幹擾佈建作業
提交版本資訊給 TA。
您也必須確保系統映像檔的版本相同 將資訊當做開機映像檔為此,我們加入了設定方法 加入 Keymaster HAL:
keymaster_error_t (*configure)(const struct keymaster2_device* dev, const keymaster_key_param_set_t* params);
params
引數包含 Tag::OS_VERSION
和
Tag::OS_PATCHLEVEL
。此方法是由 Keymaster2 用戶端呼叫
開啟 HAL 後,但在呼叫任何其他方法之前。如果任何其他方式
會在設定前呼叫,但 TA 會傳回
ErrorCode::KEYMASTER_NOT_CONFIGURED
。
裝置啟動後第一次呼叫 configure
時,
請務必確認提供的版本資訊與
開機載入器。如果版本資訊不相符
configure
會傳回 ErrorCode::INVALID_ARGUMENT
,而所有項目
其他 Keymaster 方法
ErrorCode::KEYMASTER_NOT_CONFIGURED
。如果資訊相符
configure
會傳回 ErrorCode::OK
,以及其他 Keymaster
方法。
後續對 configure
的呼叫會傳回
就不會變更 keymaster 的狀態。請注意,這項程序
所有 OTA 均須更新系統和開機映像檔。就無法更新
以便保持版本資訊同步。
因為 configure
將由其內容的系統呼叫
目的在於驗證時,攻擊者有機會利用
並強制系統提供
須符合開機映像檔,但這不是實際的系統版本。
開機映像檔驗證、系統映像檔的 dm-verity 驗證
而且 configure
在程式碼早期呼叫了
系統開機程序會讓這個窗口不易利用。