守門員子系統會在受信任的執行環境 (TEE) 中執行裝置圖案/密碼驗證。Gatekeeper 會使用硬體支援的私密金鑰註冊及驗證密碼。此外,Gatekeeper 會限制連續失敗的驗證嘗試次數,並根據指定的逾時時間和連續失敗的嘗試次數拒絕服務要求。
使用者驗證密碼時,Gatekeeper 會發出驗證權杖,該權杖會使用每個啟動 HMAC 金鑰簽署,該金鑰僅供安全元件使用,且會傳送至硬體支援的 KeyStore。也就是說,Gatekeeper 驗證權杖會通知 Keystore,讓應用程式使用驗證綁定的金鑰 (例如應用程式建立的金鑰)。
建築
Gatekeeper 包含三個主要元件:
gatekeeperd
(Gatekeeper Daemon):Android 中的 C++ Binder 服務,包含實作IGateKeeperService
AIDL 介面的平台獨立邏輯,以IGatekeeper
的底層供應商專屬實作為基礎。- Gatekeeper 硬體抽象層 (HAL) 服務:供應商專屬的
IGatekeeper
AIDL 介面實作。這項 HAL 服務會在 Android 中執行,但核心 Gatekeeper 功能需要在安全環境中執行,因此通常會與 Gatekeeper TA 通訊。 - 閘道管理員信任應用程式 (TA):供應商專屬的實作項目,會在 TEE 中執行,並執行實際的密碼或圖案驗證。
LockSettingsService
會透過 Binder 提出要求,以便在 Android 作業系統中存取 gatekeeperd
守護程式。接著,gatekeeperd
守護程序會要求 IGatekeeper
HAL 服務,而這項服務會依序在 TEE 中連至對應的 Gatekeeper TA:

圖 1. GateKeeper 驗證程序的高階資料流程。
gatekeeperd
守護程序會將 Android 架構 API 的存取權授予 HAL,並參與回報裝置驗證至 KeyStore 的作業。gatekeeperd
守護程式會在其專屬程序中執行,與系統伺服器分開。
HAL 實作
gatekeeperd
守護程序會使用 IGatekeeper
HAL 與底層 Gatekeeper TA 互動,以便進行密碼驗證。Gatekeeper TA 實作必須能夠簽署 (註冊) 及驗證 blob。所有實作都應遵循每次成功驗證密碼時產生的驗證權杖 (HardwareAuthToken
) 標準格式。如要進一步瞭解 HardwareAuthToken
的內容和語意,請參閱 HardwareAuthToken.aidl
定義。
供應商實作的 IGatekeeper
HAL 必須實作 enroll
和 verify
函式:
enroll
方法會接收密碼 blob、簽署該 blob,並以句柄的形式傳回簽名。從呼叫enroll
傳回的 blob 必須具有system/gatekeeper/include/gatekeeper/password_handle.h
所示的結構。verify
函式必須比較由提供的密碼產生的簽章,並確保該簽章與註冊的密碼句柄相符。
用於註冊和驗證的金鑰絕對不能變更,且應可在每次裝置啟動時重新衍生。
Trusty 和其他實作
Trusty 作業系統是 Google 針對 TEE 環境開發的開放原始碼受信任作業系統,其中包含已核准的 Gatekeeper 實作項目。不過,只要 TEE 可以存取持續性硬體支援金鑰,以及在暫停狀態下運作的安全單調時鐘,任何 TEE OS 都可以實作 Gatekeeper。
Trusty 會使用內部 IPC 系統,直接在 KeyMint 和 Trusty 實作 Gatekeeper (即 Trusty Gatekeeper) 之間傳遞共用密碼。這個共用密鑰會用於簽署傳送至 Keystore 的驗證權杖,以提供密碼驗證的認證。Trusty Gatekeeper 會在每次使用時向 KeyMint 要求金鑰,且不會儲存或快取該值。實作項目可以以任何不會危害安全性的做法分享此密鑰。
用於註冊及驗證密碼的 HMAC 金鑰會衍生並僅保留在 Gatekeeper 中。
Android 提供一般 C++ 守門員實作,只需新增裝置專屬例行程序即可完成;Trusty 實作方式就是以此為基礎。如要為 TEE 導入 TEE 守門員,並使用裝置專屬程式碼,請參閱 system/gatekeeper/include/gatekeeper/gatekeeper.h
中的函式和註解。符合規定的導入作業的主要責任包括:
- 遵循
IGatekeeper
HAL。 - 傳回的驗證權杖格式必須符合
HardwareAuthToken
規格 (詳見HardwareAuthToken.aidl
)。 - TEE 閘道管理員必須能夠使用下列任一方式,與 KeyMint 共用 HMAC 金鑰:
- 共用密鑰協議:Gatekeeper 可透過實作
ISharedSecret
HAL,參與每次啟動時的 HMAC 金鑰協商程序。這項操作需要 Gatekeeper 和 KeyMint 都能存取共用的預先共用密鑰。 - 直接存取:Gatekeeper 可使用 TEE 內部處理序間通訊機制,從 KeyMint 擷取 HMAC 金鑰,可視需要或在首次使用時擷取 (之後會快取)。
- 共用密鑰協議:Gatekeeper 可透過實作
使用者安全 ID (SID)
使用者 SID 是使用者的 TEE 表示法 (與 Android 使用者 ID 沒有強烈關聯)。每當使用者註冊新密碼,但未提供舊密碼時,系統就會使用加密編譯的偽隨機數字產生器 (PRNG) 產生 SID。這稱為「不受信任」的重新註冊,通常只有在使用者首次設定密碼或解鎖圖案時才會發生。
當使用者提供有效的舊密碼 (例如變更密碼時),系統就會進行可信任的重新註冊程序。在這種情況下,使用者 SID 會遷移至新的密碼句柄,並保留已繫結至該句柄的金鑰。
註冊密碼時,使用者 SID 會與密碼一起納入 HMAC 驗證,並顯示在密碼句柄中。
使用者 SID 會包含在 verify()
函式傳回的 HardwareAuthToken
中,並與所有已繫結驗證的 Keystore 金鑰建立關聯 (如要瞭解 HardwareAuthToken
格式和 Keystore 的詳細資訊,請參閱「驗證」)。
請注意,由於對 enroll()
函式的不受信任呼叫會變更使用者 SID,因此呼叫會使與該密碼繫結的金鑰變得無用。攻擊者可在控制 Android 作業系統的情況下變更裝置密碼,但會在過程中破壞受根層保護的敏感金鑰。
要求節流
Gatekeeper 必須能夠安全地限制使用者憑證的暴力破解嘗試次數。如 GatekeeperVerifyResponse.aidl
所示,HAL 會以毫秒為單位傳回逾時時間。逾時會通知用戶端在逾時後才再次呼叫 Gatekeeper。如果有待處理的逾時事件,Gatekeeper 就不會處理要求。
閘道管理員必須在驗證使用者密碼前寫入失敗計數器。如果密碼驗證成功,失敗計數器應會清除。這麼做可防止在發出 verify
呼叫後,透過停用內嵌式 MMC (eMMC) 來防止節流的攻擊。enroll
函式也會驗證使用者密碼 (如果提供),且必須以相同方式進行節流。
如果裝置支援,強烈建議您將失敗計數器寫入安全儲存空間。如果裝置不支援檔案式加密,或是安全儲存空間速度過慢,實作可能會直接使用 Replay Protected Memory Block (RPMB)。