Gatekeeper

守門員子系統會在受信任的執行環境 (TEE) 中執行裝置圖案/密碼驗證作業。Gatekeeper 會透過 HMAC 和硬體支援的密鑰,註冊及驗證密碼。此外,Gatekeeper 會限制連續失敗的驗證嘗試,並根據指定的逾時時間和連續失敗嘗試次數拒絕服務要求。

使用者驗證密碼時,Gatekeeper 會使用 TEE 衍生的共用密鑰簽署驗證認證,然後傳送至硬體支援的 Keystore。也就是說,Gatekeeper 認證會通知 Keystore,指出驗證綁定的金鑰 (例如應用程式建立的金鑰) 可供應用程式使用。

建築

Gatekeeper 包含三個主要元件:

  • gatekeeperd (總機人員 Daemon)。包含不依賴平台的邏輯,且對應至 GateKeeperService Java 介面的 C++ 繫結器服務。
  • 總機人員硬體抽象層 (HAL)hardware/libhardware/include/hardware/gatekeeper.h 中的 HAL 介面,以及實作模組。
  • 總機人員 (TEE)gatekeeperd 的 TEE 對應項目。以 TEE 為基礎的 Gatekeeper 實作項目。

Gatekeeper 需要實作 Gatekeeper HAL (具體來說是 hardware/libhardware/include/hardware/gatekeeper.h 中的函式) 和 TEE 專屬的 Gatekeeper 元件 (部分取決於 system/gatekeeper/include/gatekeeper/gatekeeper.h 標頭檔案,其中包含用於建立/存取金鑰和運算簽名的純虛擬函式)。

LockSettingsService 會透過 Binder 提出要求,以便在 Android 作業系統中存取 gatekeeperd 守護程式。接著,gatekeeperd 守護程序會向 TEE 中的對應項目 (Gatekeeper) 提出要求:

把關流程
圖 1. GateKeeper 驗證的整體資料流程

gatekeeperd 守護程序會將 Android 架構 API 的存取權授予 HAL,並參與向 Keystore 回報裝置驗證gatekeeperd 守護程式會在其專屬程序中執行,與系統伺服器分開。

HAL 實作

gatekeeperd 守護程序會使用 HAL 與 gatekeeperd 守護程序的 TEE 對應項目互動,以便進行密碼驗證。HAL 實作必須能夠簽署 (註冊) 及驗證 blob。所有實作都必須遵循每次成功驗證密碼時產生的驗證權杖 (AuthToken) 標準格式。如要進一步瞭解 AuthToken 的內容和語意,請參閱「AuthToken 格式」。

hardware/libhardware/include/hardware/gatekeeper.h 標頭檔案的實作項目必須實作 enrollverify 函式:

  • enroll 函式會採用密碼 blob、簽署密碼,並以處理常式形式傳回簽章。從 enroll 呼叫傳回的 Blob 必須具有 system/gatekeeper/include/gatekeeper/password_handle.h 中所示的結構。
  • verify 函式必須比較由提供的密碼產生的簽章,並確保該簽章與註冊的密碼句柄相符。

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

Trusty 和其他實作

Trusty 作業系統是 Google 針對 TEE 環境開發的開放原始碼信任作業系統,其中包含已核准的 GateKeeper 實作項目。不過,只要 TEE 可存取硬體支援的金鑰,以及在暫停狀態下運作的安全單調時鐘,您就可以使用任何 TEE OS 實作 Gatekeeper。

Trusty 會使用內部 IPC 系統,直接在 Keymaster 和 Trusty 實作 Gatekeeper (即 Trusty Gatekeeper) 之間傳遞共用密鑰。這個共用密鑰會用於簽署傳送至 Keystore 的 AuthToken,以提供密碼驗證的認證。Trusty Gatekeeper 每次使用時都會向 Keymaster 要求金鑰,且不會儲存或快取值。實作項目可以自由地以任何不會危害安全性的做法分享此密鑰。

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

Android 提供 GateKeeper 的一般 C++ 實作項目,只需要新增裝置專屬例程式即可完成。如要為 TEE 實作 TEE 守門員,並使用裝置專屬程式碼,請參閱 system/gatekeeper/include/gatekeeper/gatekeeper.h 中的函式和註解。針對 TEE GateKeeper,符合規定的實作項目的主要責任包括:

  • 遵循 Gatekeeper HAL。
  • 傳回的 AuthToken 必須符合 AuthToken 規格 (請參閱「驗證」一文)。
  • TEE 閘道管理員必須能夠與 Keymaster 共用 HMAC 金鑰,方法是透過 TEE IPC 按需要求金鑰,或隨時保留有效的值快取。

使用者安全 ID (SID)

User SID 是使用者的 TEE 表示法 (與 Android 使用者 ID 沒有強烈關聯)。每當使用者註冊新密碼,但未提供舊密碼時,系統就會使用加密編譯的偽隨機數字產生器 (PRNG) 產生 SID。這稱為「不受信任」的重新註冊,在一般情況下,Android 架構不允許這麼做。當使用者提供有效的舊密碼時,系統就會進行可信任的重新註冊程序;在這種情況下,User SID 會遷移至新密碼句柄,並保留與之綁定的金鑰。

註冊密碼時,使用者 SID 會與密碼一併使用 HMAC 加密。

使用者 SID 會寫入 verify 函式傳回的 AuthToken,並與所有驗證綁定的 Keystore 金鑰建立關聯 (如要進一步瞭解 AuthToken 格式和 Keystore,請參閱「驗證」)。由於對 enroll 函式的不受信任呼叫會變更使用者 SID,因此呼叫會使與該密碼繫結的金鑰失效。如果攻擊者控制 Android 作業系統,就能變更裝置密碼,但過程中會破壞受 Root 保護的敏感金鑰。

要求節流

GateKeeper 必須能夠安全地限制使用者憑證的暴力破解嘗試次數。如 hardware/libhardware/include/hardware/gatekeeper.h 所示,HAL 會以毫秒為單位傳回逾時時間。逾時會通知用戶端,在逾時前不要再次呼叫 GateKeeper;如果有待處理的逾時事件,GateKeeper 就不會處理要求。

GateKeeper 必須先寫入失敗計數器,才能驗證使用者密碼。如果密碼驗證成功,失敗計數器應會清除。這麼做可防止在發出 verify 呼叫後,透過停用內嵌式 MMC (eMMC) 來防止節流的攻擊。enroll 函式也會驗證使用者密碼 (如果提供),且必須以相同方式進行節流。

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