ゲートキーパー

ゲートキーパー サブシステムは、Trusted Execution Environment (TEE) でデバイス パターン/パスワード認証を実行します。ゲートキーパーは、HMAC を介して、ハードウェアでバックアップされた秘密鍵を使用してパスワードを登録および検証します。さらに、Gatekeeper は連続して失敗した検証試行を抑制し、指定されたタイムアウトと指定された連続失敗回数に基づいてサービス要求を拒否する必要があります。

ユーザーがパスワードを確認すると、Gatekeeper は TEE から派生した共有秘密鍵を使用して認証証明書に署名し、ハードウェアに支えられた Keystoreに送信します。つまり、Gatekeeper 構成証明は、認証にバインドされたキー (たとえば、アプリが作成したキー) をアプリで使用するために解放できることを Keystore に通知します。

建築

Gatekeeper には、次の 3 つの主要コンポーネントが含まれます。

  • gatekeeperd (ゲートキーパー デーモン)。プラットフォームに依存しないロジックを含み、 GateKeeperService Java インターフェイスに対応する C++ バインダー サービス。
  • ゲートキーパー ハードウェア アブストラクション レイヤー (HAL)hardware/libhardware/include/hardware/gatekeeper.hの HAL インターフェイスと実装モジュール。
  • ゲートキーパー (TEE)gatekeeperdの TEE 版。 Gatekeeper の TEE ベースの実装。

Gatekeeper には、 Gatekeeper HAL (具体的にはhardware/libhardware/include/hardware/gatekeeper.hの関数) とTEE 固有の Gatekeeper コンポーネント( system/gatekeeper/include/gatekeeper/gatekeeper.hヘッダー ファイルに部分的に基づく) の実装が必要です。これには、キーの作成/アクセスおよび署名の計算のための純粋仮想関数が含まれます)。

LockSettingsServiceは、Android OS のgatekeeperdデーモンに到達するリクエストを (Binder 経由で) 行います。次に、 gatekeeperdデーモンは、TEE 内の対応する (ゲートキーパー) に到達する要求を行います。

ゲートキーパー フロー
図 1. GateKeeper による認証のハイレベル データ フロー

gatekeeperdデーモンは、Android フレームワーク API に HAL へのアクセスを許可し、キーストアへのデバイス認証の報告に参加します。 gatekeeperdデーモンは独自のプロセスで実行され、システム サーバーから分離されています。

HAL の実装

gatekeeperdデーモンは HAL を使用して、 gatekeeperdデーモンの対応する TEE と対話し、パスワード認証を行います。 HAL 実装は、BLOB に署名 (登録) および検証できる必要があります。すべての実装は、パスワード検証が成功するたびに生成される認証トークン (AuthToken) の標準形式に準拠する必要があります。 AuthToken の内容とセマンティックの詳細については、 AuthToken の形式を参照してください。

hardware/libhardware/include/hardware/gatekeeper.hヘッダー ファイルの実装では、 enroll機能とverify機能を実装する必要があります。

  • enroll関数は、パスワード blob を取得して署名し、署名をハンドルとして返します。返された blob ( enrollの呼び出しから) は、 system/gatekeeper/include/gatekeeper/password_handle.h示されている構造を持っている必要があります。
  • verify機能は、提供されたパスワードによって生成された署名を比較し、登録されたパスワード ハンドルと一致することを確認する必要があります。

登録と検証に使用されるキーは決して変更してはならず、デバイスの起動ごとに再導出できる必要があります。

Trusty およびその他の実装

Trustyオペレーティング システムは、TEE 環境向けの Google のオープン ソースの信頼できる OS であり、GateKeeper の承認された実装が含まれています。ただし、TEE がハードウェアでバックアップされたキーと、 suspend で時を刻む安全で単調なクロックにアクセスできる限り、任意の TEE OSを使用して Gatekeeper を実装できます。

Trusty は、内部 IPC システムを使用して、Keymaster と Gatekeeper の Trusty 実装 ( Trusty Gatekeeper ) との間で共有シークレットを直接通信します。この共有シークレットは、パスワード検証の証明を提供するためにキーストアに送信される AuthToken に署名するために使用されます。 Trusty Gatekeeper は、使用のたびに Keymaster からキーを要求し、値を永続化またはキャッシュしません。実装は、セキュリティを損なわない方法でこのシークレットを自由に共有できます。

パスワードの登録と検証に使用される HMAC キーは、GateKeeper でのみ生成され、保持されます。

Android は、デバイス固有のルーチンを追加するだけで完了する GateKeeper の汎用 C++ 実装を提供します。 TEE のデバイス固有のコードを使用して TEE ゲートキーパーを実装するには、 system/gatekeeper/include/gatekeeper/gatekeeper.hの関数とコメントを参照してください。 TEE GateKeeper の場合、準拠した実装の主な責任には以下が含まれます。

  • ゲートキーパー HAL への準拠。
  • 返される AuthToken は、AuthToken 仕様 ( Authenticationで説明) に従ってフォーマットする必要があります。
  • TEE ゲートキーパーは、オンデマンドで TEE IPC を介してキーを要求するか、値の有効なキャッシュを常に維持することにより、Keymaster と HMAC キーを共有できる必要があります。

ユーザーセキュア ID (SID)

ユーザー SID は、ユーザーの TEE 表現です (Android ユーザー ID との強い関連はありません)。 SID は、ユーザーが以前のパスワードを提供せずに新しいパスワードを登録するたびに、暗号化疑似乱数ジェネレーター (PRNG) を使用して生成されます。これは、信頼されていない再登録と呼ばれ、通常の状況では Android フレームワークによって許可されません。ユーザーが有効な以前のパスワードを提供すると、信頼できる再登録が行われます。この場合、ユーザー SID は新しいパスワード ハンドルに移行され、それにバインドされていたキーが保持されます。

ユーザー SID は、パスワードが登録されるときに、パスワード ハンドル内のパスワードと共に HMAC されます。

ユーザー SID は、 verify関数によって返された AuthToken に書き込まれ、すべての認証バインド キーストア キーに関連付けられます (AuthToken 形式とキーストアの詳細については、 Authenticationを参照してください)。 enroll機能への信頼されていない呼び出しはユーザー SID を変更するため、呼び出しはそのパスワードにバインドされたキーを役に立たなくします。攻撃者は、Android OS を制御している場合、デバイスのパスワードを変更できますが、その過程でルート保護された機密キーを破壊します。

スロットリングのリクエスト

GateKeeper は、ユーザー資格情報に対するブルート フォース試行を安全に抑制できる必要があります。 hardware/libhardware/include/hardware/gatekeeper.hに示されているように、HAL はミリ秒単位でタイムアウトを返します。タイムアウトは、タイムアウトが経過するまで GateKeeper を再度呼び出さないようにクライアントに通知します。保留中のタイムアウトがある場合、GateKeeper は要求を処理しません。

GateKeeper は、ユーザーのパスワードを検証する前に、失敗カウンターを書き込む必要があります。パスワードの検証が成功した場合は、失敗カウンターをクリアする必要があります。これにより、 verify呼び出しの発行後に組み込み MMC (eMMC) を無効にすることでスロットリングを防止する攻撃を防ぎます。 enroll機能は、ユーザー パスワード (提供されている場合) も検証し、同じ方法で調整する必要があります。

デバイスでサポートされている場合は、障害カウンターを安全なストレージに書き込むことを強くお勧めします。デバイスがファイルベースの暗号化をサポートしていない場合、または安全なストレージが遅すぎる場合、実装では Replay Protected Memory Block (RPMB) を直接使用できます。