指紋認証 HIDL

指紋認証センサーを備えたデバイスでは、ユーザーが 1 つ以上の指紋を登録してデバイスのロック解除などの操作に使用できます。Android は指紋認証ハードウェア インターフェース定義言語(HIDL)を使用して、ベンダー固有のライブラリと指紋認証ハードウェア(指紋認証センサーなど)に接続します。

指紋認証 HIDL を実装するには、ベンダー固有のライブラリに IBiometricsFingerprint.hal を実装する必要があります。

指紋照合

通常、デバイスの指紋認証センサーはアイドル状態です。ただし、authenticate または enroll の呼び出しに応じて、指紋認証センサーはタッチをリッスンします(ユーザーが指紋認証センサーにタッチすると画面が復帰する場合もあります)。指紋照合の上位のフローには、次の手順が含まれます。

  1. ユーザーが指紋認証センサーに指を当てます。
  2. ベンダー固有のライブラリは、現在登録されている指紋テンプレートに一致する指紋があるかどうかを特定します。
  3. 一致する結果が FingerprintService に渡されます。

このフローでは、指紋がデバイスにすでに登録されていることを前提としています。つまり、ベンダー固有のライブラリには指紋のテンプレートが登録されています。詳しくは、認証をご覧ください。

アーキテクチャ

指紋認証 HAL は、次のコンポーネントとやり取りします。

  • BiometricManager はアプリプロセスでアプリと直接やり取りします。 アプリごとに IBiometricsFingerprint.hal のインスタンスがあります。
  • FingerprintService は、指紋認証 HAL との通信を処理するシステム プロセスで動作します。
  • 指紋認証 HAL は、IBiometricsFingerprint HIDL インターフェースの C または C++ 実装です。これには、デバイス固有のハードウェアと通信するベンダー固有のライブラリが含まれます。
  • Keystore API と Keymaster コンポーネントは、Trusted Execution Environment(TEE)などの安全な環境で安全に鍵を保管するために、ハードウェア格納型暗号を提供します。
指紋認証のデータフロー
図 1. 指紋認証のデータフローの概要

ベンダー固有の HAL 実装では、TEE で必要な通信プロトコルを使用する必要があります。未処理の画像と処理済みの指紋の特徴は、信頼できないメモリに渡さないでください。このような生体認証データはすべて、TEE などのセキュア ハードウェアに保存する必要があります。ルート権限取得によって生体認証データが侵害されないようにする必要があります。

FingerprintServicefingerprintd は指紋認証 HAL を使用してベンダー固有のライブラリを呼び出し、指紋の登録などの操作を実行します。

fingerprintd とのやり取り
図 2. 指紋認証デーモンと指紋認証のベンダー固有ライブラリのやり取り

実装ガイドライン

次の指紋認証 HAL ガイドラインは、デバイスからユーザーが削除されたときに指紋データが漏洩することなく削除されることを目的に作成されています。

  • 未処理の指紋データや派生物(テンプレートなど)には、センサー ドライバまたは TEE の外部からアクセスできないようにしてください。ハードウェアで TEE がサポートされている場合、ハードウェア アクセスを TEE に制限し、SELinux ポリシーで保護する必要があります。シリアル ペリフェラル インターフェース(SPI)チャネルには TEE だけがアクセスできるようにして、すべてのデバイス ファイルに明示的な SELinux ポリシーが必要です。
  • 指紋の取得、登録、認識は TEE 内で行う必要があります。
  • ファイル システム自体が暗号化される場合でも、ファイル システムに保存できるのは、暗号化された形式の指紋データのみです。
  • 指紋テンプレートは、デバイス固有の秘密鍵を使用して署名する必要があります。 AES(Advanced Encryption Standard)の場合は、テンプレート ファイルを他のデバイスで使用したり、デバイスに登録したユーザー以外が使用したりできないように、少なくともテンプレートをファイルシステムの絶対パス、グループ、指紋 ID で署名する必要があります。たとえば、同じデバイスで別のユーザーの指紋データをコピーしたり、別のデバイスから指紋データをコピーしたりすることはできません。
  • 実装では、setActiveGroup() 関数によって提供されるファイルシステム パスを使用するか、ユーザーが削除されたときにすべてのユーザー テンプレート データを消去する方法を指定する必要があります。指紋テンプレート ファイルは、暗号化した状態で指定のパスに保存することを強くおすすめします。TEE ストレージ要件のためにこの方法で保存できない場合は、ユーザーを削除したときにデータが確実に削除されるようにフックを追加する必要があります。

指紋認証メソッド

指紋認証 HIDL インターフェースには、IBiometricsFingerprint.hal の次の主要メソッドが含まれています。

メソッド 説明
enroll() HAL ステートマシンを切り替えて、指紋テンプレートの収集と保存を開始します。登録が完了するか、タイムアウトすると、HAL ステートマシンはアイドル状態に戻ります。
preEnroll() 指紋の登録の開始を示す一意のトークンを生成します。トークンを enroll 関数に提供し、パスワードなどを使用して事前認証が行われていることを確認します。改ざんを防ぐため、トークンはデバイスの認証情報が確認された後でラップされます。登録時にトークンが有効であることを確認する必要があります。
getAuthenticatorId() 現在の指紋セットに関連付けられたトークンを返します。
cancel() 保留中の登録操作または認証操作をキャンセルします。HAL ステートマシンはアイドル状態に戻ります。
enumerate() 既知の指紋テンプレートをすべて列挙するために同期呼び出しを行います。
remove() 指紋テンプレートを削除します。
setActiveGroup() グループ ID(GID)で識別される、指定のグループに属する一連の指紋に HAL 操作を制限します。
authenticate() 指紋関連の操作(操作 ID で識別)を認証します。
setNotify() HAL からの通知を受け取るユーザー関数を登録します。HAL ステートマシンがビジー状態になると、この関数は HAL がビジー状態から移行するまでブロックされます。
postEnroll() 登録操作を終了し、preEnroll() で生成されたチャレンジを無効化します。他に追加する指紋がないことを示すために、複数の指紋登録セッションの最後に呼び出す必要があります。

これらについて詳しくは、IBiometricsFingerprint.hal のコメントをご覧ください。