このページでは、KeyMint Hardware Abstraction Layer(HAL: ハードウェア抽象化レイヤ)の実装に役立つ詳細情報とガイドラインを掲載します。HAL の主なドキュメントは、AIDL インターフェース仕様です。
API の不正使用
呼び出し元は、API パラメータとして有効な承認を使用して KeyMint 鍵を作成できますが、その結果、鍵が安全でなくなったり、使用できなくなったりする可能性があります。 そのような場合、KeyMint 実装でエラーや診断メッセージを発行する必要はありません。小さすぎる鍵を使用する、無関係な入力パラメータを指定する、IV またはノンスを再使用する、目的を持たない(したがって無用な)鍵を生成するなどの誤りは、実装で診断するべき問題ではありません。
KeyMint モジュールの呼び出しが意味のある有用な行為であることは、アプリ、フレームワーク、Android キーストアによって保証されます。
addRngEntropy エントリー ポイント
addRngEntropy エントリー ポイントは、鍵と IV の乱数を生成するために KeyMint
実装が使用するプールに、呼び出し元が提供するエントロピーを追加します。
KeyMint 実装は、提供されたエントロピーをセキュアな方法でプールに混合する必要があります。プールには、ハードウェア乱数ジェネレータから内部的に生成されたエントロピーも含まれている必要があります。混合の処理により、addRngEntropy
が提供するビットまたはハードウェアで生成されたビットの両方ではなくいずれかを完全に制御できる攻撃者に、エントロピー
プールから生成されるビットを予測するための有利な手掛かりを与えないようにする必要があります。
鍵特性
KeyMint 鍵を作成する各メカニズム(generateKey、importKey、importWrappedKey)は、新しく作成された鍵の特性を、各特性を適用するセキュリティ
レベルに適切に分割して返します。返される特性には、鍵の作成に指定されたすべてのパラメータ(Tag::APPLICATION_ID と
Tag::APPLICATION_DATA を除く)が含まれます。
これらのタグが鍵パラメータに含まれている場合、返される特性からそれらのタグが削除され、返された鍵
blob を調べてもそれらの値を見つけることはできなくなります。ただし、それらは暗号として鍵 blob
にバインドされているため、鍵の使用時に正しい値が指定されなければ、使用は失敗します。同様に、Tag::ROOT_OF_TRUST
は暗号として鍵にバインドされますが、鍵の作成時またはインポート時には指定できず、返されることはありません。
提供されたタグに加えて、KeyMint 実装は Tag::ORIGIN も追加します。これは、鍵が作成された方法(KeyOrigin::GENERATED、KeyOrigin::IMPORTED、または
KeyOrigin::SECURELY_IMPORTED)を示します。
ロールバック耐性
ロールバック耐性は Tag::ROLLBACK_RESISTANCE で示されます。これは、deleteKey または deleteAllKeys
で鍵を削除すると、セキュア ハードウェアによって二度と使用できなくなることを意味します。
KeyMint 実装は、生成またはインポートされた鍵マテリアルを鍵 blob(暗号化された認証済みのフォーム)として呼び出し元に返します。キーストアが鍵 blob を削除すると鍵はなくなりますが、以前鍵マテリアルの取得に成功した攻撃者がデバイスに鍵を復元できる可能性があります。
削除された鍵を後で復元できないことをセキュア ハードウェアが保証していれば、鍵はロールバック耐性を持ちます。これは通常、攻撃者が操作できない信頼できる場所に追加の鍵メタデータを格納することで実現されます。モバイル デバイスでは、このためのメカニズムとして、リプレイ保護メモリブロック(RPMB)がよく使用されます。作成できる鍵の数は本質的に無制限であり、ロールバック耐性用の信頼できるストレージのサイズには制限があるため、ストレージがいっぱいになると、ロールバック耐性のある鍵を作成するリクエストが失敗する可能性があります。
begin
begin() エントリー
ポイントは、指定された鍵で、指定された目的のために、指定されたパラメータを(必要に応じて)使用して暗号オペレーションを開始します。オペレーションを完了するために使用される新しい
IKeyMintOperation Binder オブジェクトを返します。また、認証済みオペレーションで認証トークンの一部として使用されるチャレンジ値が返されます。
KeyMint 実装は、少なくとも 16 個の同時実行オペレーションをサポートします。キーストアは最大 15 個の同時実行オペレーションを使用し、1
つはパスワード暗号化で使用するために vold として取って置きます。キーストアで 15 個のオペレーションが実行されている(begin() は
呼び出し済みだが finish または abort はまだ
呼び出されていない)ときに、キーストアが 16 番目のオペレーションを開始するリクエストを受信すると、有効なオペレーションの数を 14 に減らすために、最後に使用されたオペレーションで
abort() を呼び出した後、begin() を呼び出して新たにリクエストされたオペレーションを開始します。
鍵の生成またはインポート時に Tag::APPLICATION_ID または Tag::APPLICATION_DATA が指定された場合、begin()
の呼び出しには、このメソッドに対する params 引数で最初に指定された値を持つそれらのタグが挿入されます。
エラー処理
IKeyMintOperation のメソッドが ErrorCode::OK 以外のエラーコードを返すと、オペレーションは中止され、オペレーション
Binder オブジェクトは無効化されます。その後、オブジェクトを使用すると、ErrorCode::INVALID_OPERATION_HANDLE
が返されます。
承認の適用
鍵承認の適用は、主として begin() で行われます。唯一の例外は、鍵に 1 つ以上の Tag::USER_SECURE_ID
値があり、Tag::AUTH_TIMEOUT 値がない場合です。
この場合、鍵はオペレーションごとに承認を必要とし、update() または finish() メソッドは authToken 引数で認証トークンを受け取ります。トークンが有効であることを確認するために、KeyMint
実装は次の処理を行います。
- 認証トークンの HMAC 署名を検証します。
- トークンに、鍵に関連付けられたセキュア ユーザー ID と一致する ID が含まれていることを確認します。
- トークンの認証タイプが鍵の
Tag::USER_AUTH_TYPEと一致していることを確認します。 - トークンの challenge フィールドに、現在のオペレーションのチャレンジ値が含まれていることを確認します。
これらの条件が満たされない場合、KeyMint は ErrorCode::KEY_USER_NOT_AUTHENTICATED を返します。
呼び出し元は、update() と finish() のすべての呼び出しに対して認証トークンを提供します。実装では、一度だけトークンを検証できます。