KeyMint 函式

本頁面提供額外的詳細資料和指南,協助實作 KeyMint 硬體抽象層 (HAL)。HAL 的主要說明文件是 AIDL 介面規格

濫用 API

呼叫端可以建立 KeyMint 金鑰,授權可做為有效的 API 參數,但會導致產生的金鑰不安全或無法使用。KeyMint 實作項目不一定要在這種情況下失敗或發布診斷資訊。實作項目不應診斷使用過小的金鑰、指定不相關的輸入參數、重複使用 IV 或隨機數、產生沒有用途 (因此無用) 的金鑰等問題。

應用程式、架構和 Android Keystore 必須確保對 KeyMint 模組的呼叫合理且實用。

addRngEntropy 進入點

addRngEntropy 進入點會將呼叫端提供的熵新增至 KeyMint 實作使用的集區,以產生隨機數字、金鑰和 IV。

KeyMint 實作項目必須將提供的資訊熵安全地混入集區,該集區也必須包含來自硬體隨機數字產生器的內部產生資訊熵。應妥善處理混合作業,確保攻擊者完全掌控 addRngEntropy 提供的位元或硬體產生的位元 (但不是兩者) 時,不會在預測熵集區產生的位元時佔有顯著優勢。

主要特徵

建立 KeyMint 金鑰的每個機制 (generateKeyimportKeyimportWrappedKey) 都會傳回新建立金鑰的特徵,並適當劃分為強制執行各項特徵的安全等級。傳回的特徵包括為建立金鑰指定的所有參數,但 Tag::APPLICATION_IDTag::APPLICATION_DATA 除外。如果這些標記包含在金鑰參數中,系統會從傳回的特徵中移除這些標記,因此無法透過檢查傳回的 keyblob 找出這些標記的值。不過,這些值會以密碼編譯方式繫結至 keyblob,因此如果使用金鑰時未提供正確值,就會導致使用失敗。同樣地,Tag::ROOT_OF_TRUST 會以密碼編譯方式繫結至金鑰,但無法在建立或匯入金鑰時指定,且永遠不會傳回。

除了提供的標記,KeyMint 實作也會新增 Tag::ORIGIN,指出金鑰的建立方式 (KeyOrigin::GENERATEDKeyOrigin::IMPORTEDKeyOrigin::SECURELY_IMPORTED)。

無法復原

Tag::ROLLBACK_RESISTANCE 表示具備復原防護機制,也就是說,一旦使用 deleteKeydeleteAllKeys 刪除金鑰,安全硬體就會確保金鑰永遠無法再次使用。

KeyMint 實作會以 keyblob (加密及經過驗證的形式),將產生或匯入的金鑰內容傳回給呼叫端。Keystore 刪除 keyblob 時,金鑰就會消失,但如果攻擊者先前設法擷取金鑰內容,就可能將金鑰還原至裝置。

如果安全硬體可確保刪除的金鑰日後無法還原,則該金鑰可防止回溯。一般來說,做法是在攻擊者無法操控的信任位置儲存額外的金鑰中繼資料。在行動裝置上,這項機制通常會使用重播保護記憶體區塊 (RPMB)。由於可建立的鍵數量基本上沒有上限,且用於防回溯的信任儲存空間大小可能有限,因此當儲存空間已滿時,實作可能會導致建立防回溯鍵的要求失敗。

開始

begin() 進入點會使用指定金鑰,以指定用途和指定參數 (視情況) 開始執行加密編譯作業。這個方法會傳回新的 IKeyMintOperation Binder 物件,用於完成作業。此外,系統也會傳回挑戰值,做為已驗證作業中驗證權杖的一部分。

KeyMint 實作項目至少支援 16 個並行作業。Keystore 最多會使用 15 個,因此 vold 還有一個可供密碼加密。如果 Keystore 有 15 項作業正在進行中 (已呼叫 begin(),但尚未呼叫 finishabort),且收到開始第 16 項作業的要求,Keystore 會對最近最少使用的作業呼叫 abort(),將進行中的作業數量減少至 14 項,然後呼叫 begin() 來開始新要求作業。

如果在金鑰產生或匯入期間指定了 Tag::APPLICATION_IDTag::APPLICATION_DATA,對 begin() 的呼叫必須在 params 引數中包含這些標記,以及原始指定的值。

處理錯誤

如果 IKeyMintOperation 的方法傳回的錯誤代碼不是 ErrorCode::OK,作業就會中止,且作業 Binder 物件會失效。日後使用該物件時,會傳回 ErrorCode::INVALID_OPERATION_HANDLE

授權強制執行

金鑰授權強制執行作業主要在 begin() 中進行。但如果鍵有一個以上的 Tag::USER_SECURE_ID 值,且沒有 Tag::AUTH_TIMEOUT 值,則不在此限。

在這種情況下,金鑰需要每個作業的授權,且 update()finish() 方法會在 authToken 引數中收到授權權杖。為確保權杖有效,KeyMint 實作項目必須:

  • 驗證授權權杖的 HMAC 簽章。
  • 檢查權杖是否包含與金鑰相關聯的安全使用者 ID。
  • 檢查權杖的驗證類型是否與金鑰的 Tag::USER_AUTH_TYPE 相符。
  • 檢查權杖的挑戰欄位是否包含目前作業的挑戰值。

如果不符合這些條件,KeyMint 會傳回 ErrorCode::KEY_USER_NOT_AUTHENTICATED

呼叫端會為每次對 update()finish() 的呼叫提供驗證權杖。實作項目只能驗證權杖一次。