このページでは、KeyMint Hardware Abstraction Layer(HAL)の実装に役立つ詳細情報とガイドラインを紹介します。HAL の主なドキュメントは、AIDL インターフェースの仕様です。
API の誤った使用
呼び出し元は、API パラメータとして有効な認可を使用して KeyMint 鍵を作成できますが、生成された鍵が安全でないか、使用できなくなります。そのような場合、KeyMint 実装でエラーや診断メッセージを発行する必要はありません。小さすぎる鍵を使用する、無関係な入力パラメータを指定する、IV またはノンスを再使用する、目的を持たない(したがって無用な)鍵を生成するなどの誤りは、実装で診断するべき問題ではありません。
KeyMint モジュールの呼び出しが意味のある有用な行為であることは、アプリ、フレームワーク、Android キーストアによって保証されます。
addRngEntropy エントリ ポイント
addRngEntropy
エントリ ポイントは、KeyMint 実装が乱数、鍵、IV の生成に使用するプールに、呼び出し元が提供するエントロピーを追加します。
KeyMint 実装は、提供されたエントロピーをセキュアな方法でプールに混合する必要があります。プールには、ハードウェア乱数ジェネレータから内部的に生成されたエントロピーも含まれている必要があります。混合の処理により、addRngEntropy
が提供するビットまたはハードウェアで生成されたビットの両方ではなくいずれかを完全に制御できる攻撃者に、エントロピー プールから生成されるビットを予測するための有利な手掛かりを与えないようにする必要があります。
鍵特性
KeyMint 鍵を作成する各メカニズム(generateKey
、importKey
、importWrappedKey
)は、新しく作成された鍵の特性を返します。この特性は、各特性を適用するセキュリティ レベルに適切に分割されます。返される特性には、鍵の作成に指定されたすべてのパラメータ(Tag::APPLICATION_ID
と Tag::APPLICATION_DATA
を除く)が含まれます。これらのタグが鍵パラメータに含まれていた場合、返される特性からそれらのタグが削除され、返された鍵 blob を調べてもそれらの値を見つけることはできなくなります。ただし、それらは暗号として鍵 blob にバインドされているため、鍵の使用時に正しい値が指定されなければ、使用は失敗します。同様に、Tag::ROOT_OF_TRUST
は暗号として鍵にバインドされますが、鍵の作成時またはインポート時には指定できず、返されることはありません。
指定されたタグに加えて、KeyMint の実装では、鍵の作成方法(KeyOrigin::GENERATED
、KeyOrigin::IMPORTED
、KeyOrigin::SECURELY_IMPORTED
)を示す Tag::ORIGIN
も追加されます。
ロールバック耐性
ロールバック耐性は 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 が含まれていることを確認します。
- トークンの認証タイプが鍵の
Tag::USER_AUTH_TYPE
と一致することを確認します。 - トークンの challenge フィールドに、現在のオペレーションの challenge 値が含まれていることを確認します。
これらの条件が満たされていない場合、KeyMint は ErrorCode::KEY_USER_NOT_AUTHENTICATED
を返します。
呼び出し元は、update()
と finish()
のすべての呼び出しに対して認証トークンを提供します。実装でトークンを検証できるのは 1 回のみです。