Gatekeeper

Gatekeeper 子系統會在受信任的執行環境 (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 通訊。
  • Gatekeeper 受信任應用程式 (TA):在 TEE 中執行的供應商專屬實作項目,可執行實際的密碼或圖案驗證。

LockSettingsService 會發出要求 (透過 Binder),該要求會傳送至 Android OS 中的 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 時,必須實作 enrollverify 函式:

  • enroll 方法會取得密碼 Blob、簽署該 Blob,並以控制代碼形式傳回簽章。傳回的 Blob (來自對 enroll 的呼叫) 必須具有 system/gatekeeper/include/gatekeeper/password_handle.h 中顯示的結構。
  • verify 函式必須比較提供的密碼產生的簽章,並確保簽章與已註冊的密碼控制代碼相符。

用於註冊和驗證的金鑰絕不能變更,且應可在每次裝置啟動時重新衍生。

Trusty 和其他實作方式

Trusty 作業系統是 Google 為 TEE 環境提供的開放原始碼受信任 OS,內含經核准的 Gatekeeper 實作項目。不過,只要 TEE 能存取持續性硬體支援金鑰和安全單調時鐘 (在暫停時會滴答作響)任何 TEE OS 都能實作 Gatekeeper。

Trusty 會使用內部 IPC 系統,在 KeyMint (先前為 Keymaster) 和 Trusty 實作的 Gatekeeper (即 Trusty Gatekeeper) 之間直接傳輸共用密鑰。這個共用密碼會用於簽署傳送至 Keystore 的 AuthToken,以提供密碼驗證的認證。Trusty Gatekeeper 會在每次使用時向 KeyMint 要求金鑰,不會保留或快取金鑰值。實作項目可自由分享這個密鑰,只要不影響安全性即可。

用於註冊及驗證密碼的 HMAC 金鑰只會衍生並保留在 Gatekeeper 中。

Android 提供通用的 C++ Gatekeeper 實作,只需要新增裝置專屬的常式即可完成;Trusty 實作就是以這個為基礎。如要使用 TEE 的裝置專屬程式碼實作 TEE Gatekeeper,請參閱 system/gatekeeper/include/gatekeeper/gatekeeper.h 中的函式和註解。符合規範的導入作業主要包括:

  • 遵守 IGatekeeper HAL。
  • 傳回的驗證權杖格式必須符合 HardwareAuthToken 規格 (如「驗證」一文所述)。
  • TEE Gatekeeper 必須能夠與 KeyMint 共用 HMAC 金鑰,方法是透過 TEE IPC 隨選要求金鑰,或隨時維護值的有效快取。

使用者安全 ID (SID)

使用者 SID 是使用者在 TEE 中的代表 (與 Android 使用者 ID 沒有強烈關聯)。每當使用者註冊新密碼 (未提供舊密碼) 時,系統就會使用加密編譯虛擬隨機數產生器 (PRNG) 產生 SID。這稱為「不信任」重新註冊,通常只會在使用者首次設定密碼或解鎖圖案時發生。

使用者提供有效的舊密碼時 (例如變更密碼時),系統會進行信任重新註冊。在這種情況下,使用者 SID 會遷移至新的密碼控制代碼,並保留繫結至該控制代碼的金鑰。

註冊密碼時,使用者 SID 會連同密碼控制代碼中的密碼一併納入 HMAC 驗證。

使用者 SID 會納入 verify() 函式傳回的 HardwareAuthToken 中,並與所有繫結至驗證的 Keystore 金鑰建立關聯 (如要瞭解 HardwareAuthToken 格式和 Keystore 的詳細資料,請參閱「驗證」)。

請注意,由於對 enroll() 函式的不受信任呼叫會變更使用者 SID,因此該呼叫會導致繫結至該密碼的金鑰失效。如果攻擊者控制 Android OS,就能變更裝置密碼,但他們會在過程中毀損受 Root 權限保護的私密金鑰。

要求節流

Gatekeeper 必須能夠安全地限制使用者憑證的暴力破解嘗試次數。如 GatekeeperVerifyResponse.aidl 所示,HAL 會提供以毫秒為單位的逾時時間。逾時時間會通知用戶端,在逾時時間結束前不要再次呼叫 Gatekeeper。如有待處理的逾時,Gatekeeper 就不應處理要求。

Gatekeeper 必須先寫入失敗計數器,才能驗證使用者密碼。如果密碼驗證成功,失敗計數器應會清除。這樣做可避免攻擊,因為系統會在發出 verify 呼叫後停用內嵌式 MMC (eMMC),防止節流。enroll 函式也會驗證使用者密碼 (如有提供),且必須以相同方式節流。

如果裝置支援,強烈建議將失敗計數器寫入安全儲存空間。如果裝置不支援檔案型加密,或安全儲存空間速度太慢,實作項目可能會直接使用 Replay Protected Memory Block (RPMB)。