Keymaster の関数

このページでは、Keymaster Hardware Abstraction Layer(HAL: ハードウェア抽象レイヤ)の実装に役立つ詳細情報を掲載します。API の各関数、その関数を使用できる Keymaster のバージョン、デフォルトの実装を示します。タグについては、Keymaster タグのページをご覧ください。

一般的な実装のガイドライン

以下のガイドラインは、API のすべての関数に適用されます。

入力ポインタ パラメータ

バージョン: 1、2

特定の呼び出しで使用されていない入力ポインタ パラメータに NULL を指定できます。呼び出し元は、プレースホルダを提供する必要はありません。たとえば、一部の鍵タイプとモードでは、begin に対して inParams 引数を使用しないことがあるため、呼び出し元は inParamsNULL に設定して空のパラメータ セットを渡すことができます。呼び出し元は使用されないパラメータを渡すこともできます。これに対して Keymaster メソッドはエラーを発行することはできません。

必須の入力パラメータが NULL の場合、Keymaster メソッドは ErrorCode::UNEXPECTED_NULL_POINTER を返す必要があります。

Keymaster 3 以降では、ポインタ パラメータはありません。すべてのパラメータは、値または const 参照によって渡されます。

出力ポインタ パラメータ

バージョン: 1、2

入力ポインタ パラメータと同様に、使用されない出力ポインタ パラメータに NULL を指定できます。 NULL であると判明した出力パラメータのデータをメソッドが返さなくてはならない場合は、ErrorCode::OUTPUT_PARAMETER_NULL を返す必要があります。

Keymaster 3 以降では、ポインタ パラメータはありません。すべてのパラメータは、値または const 参照によって渡されます。

API の誤った使用

バージョン: 1、2、3

無意味だが技術的な誤りはないリクエストを呼び出し元が実行することは数多くあります。そのような場合、Keymaster 実装でエラーや診断メッセージを発行する必要はありません。小さすぎる鍵を使用する、無関係な入力パラメータを指定する、IV またはノンスを再使用する、目的を持たない(したがって無用な)鍵を生成するなどの誤りは、実装で診断するべき問題ではありません。診断するべき問題は、必須パラメータの省略、無効な必須パラメータの指定、およびそれに類する誤りです。

Keymaster モジュールの呼び出しが意味のある有用な行為であることは、アプリ、フレームワーク、Android キーストアによって保証されます。

関数

getHardwareFeatures

バージョン: 3

新しい getHardwareFeatures メソッドは、基盤となるセキュア ハードウェアの重要な特性をクライアントに公開します。このメソッドは引数を取らず、4 つの値(すべてブール値)を返します。

  • isSecure は、鍵がセキュア ハードウェア(TEE など)に格納されてその中にとどまる場合に、true になります。
  • supportsEllipticCurve は、ハードウェアが NIST 曲線(P-224、P-256、P-384、P-521)を使用した楕円曲線暗号をサポートしている場合に、true になります。
  • supportsSymmetricCryptography は、ハードウェアが AES や HMAC などの対称暗号をサポートしている場合に、true になります。
  • supportsAttestation は、ハードウェアがセキュア環境で注入された鍵で署名された Keymaster 公開鍵構成証明書の生成をサポートしている場合に、true になります。

このメソッドが返すエラーコードは、ErrorCode:OKErrorCode::KEYMASTER_NOT_CONFIGURED、またはセキュア ハードウェアとの通信に失敗したことを示すエラーコードのいずれかです。

    getHardwareFeatures()
        generates(bool isSecure, bool supportsEllipticCurve, bool supportsSymmetricCryptography,
                  bool supportsAttestation, bool supportsAllDigests, string keymasterName,
                  string keymasterAuthorName);

configure

バージョン: 2

この関数は Keymaster 2 で導入され、Keymaster 3 でサポートが終了しました。この情報はシステム プロパティ ファイルで使用でき、メーカー実装は起動時に該当ファイルを読み取ります。

Keymaster を構成します。このメソッドは、デバイスを開いてから使用するまでの間に呼び出されます。KM_TAG_OS_VERSIONKM_TAG_OS_PATCHLEVEL を Keymaster に提供するために使用されます。このメソッドが呼び出されるまで、他のすべてのメソッドは KM_ERROR_KEYMASTER_NOT_CONFIGURED を返します。このメソッドが提供する値は、起動ごとに Keymaster により一度だけ受け入れられます。その後で呼び出されると、KM_ERROR_OK を返すだけで何もしません。

Keymaster 実装がセキュア ハードウェア内にあり、OS バージョンとパッチレベルの値がブートローダーによってセキュア ハードウェアに提供された値と一致しない場合(またはブートローダーが値を提供しなかった場合)、このメソッドは KM_ERROR_INVALID_ARGUMENT を返し、他のすべてのメソッドは引き続き KM_ERROR_KEYMASTER_NOT_CONFIGURED を返します。

    keymaster_error_t (*configure)(const struct keymaster2_device* dev,
                                   const keymaster_key_param_set_t* params);

addRngEntropy

バージョン: 1、2、3

この関数は Keymaster 1 で add_rng_entropy として導入され、Keymaster 3 で改名されました。

鍵や IV などで乱数を生成するために Keymaster 1 実装が使用するプールに、呼び出し元が提供するエントロピーを追加します。

Keymaster 実装は、提供されたエントロピーをセキュアな方法でプールに混合する必要があります。プールには、ハードウェア乱数ジェネレータから内部的に生成されたエントロピーも含まれている必要があります。混合の処理により、addRngEntropy が提供するビットまたはハードウェアで生成されたビットの両方ではなくいずれかを完全に制御できる攻撃者に、エントロピー プールから生成されるビットを予測するための有利な手掛かりを与えないようにする必要があります。

内部プールのエントロピーを推定しようとする Keymaster 実装は、addRngEntropy が提供するデータにはエントロピーが含まれていないと想定します。Keymaster 実装は、1 回の呼び出しで 2 KiB を超えるデータを渡されると、ErrorCode::INVALID_INPUT_LENGTH を返す可能性があります。

generateKey

バージョン: 1、2、3

この関数は Keymaster 1 で generate_key として導入され、Keymaster 3 で改名されました。

鍵に恒久的にバインドされる関連認証を指定して、新しい暗号鍵を生成します。Keymaster 実装は、生成時に指定された認証と矛盾する方法で鍵を使用できないようにします。セキュア ハードウェアが適用できない承認については、セキュア ハードウェアの責務は、鍵に関連付けられた適用できない承認を変更不可にすることに限定されているため、すべての getKeyCharacteristics 呼び出しは元の値を返します。また、generateKey によって返される特性によって、ハードウェア適用リストとソフトウェア適用リストのそれぞれに、適切な認証が割り当てられます。詳細については、getKeyCharacteristics をご覧ください。

generateKey に渡されるパラメータは、生成される鍵のタイプによって異なります。以下のセクションでは、鍵のタイプごとに必須のタグと省略可能なタグの要約を示します。型を指定するには、Tag::ALGORITHM が常に必要です。

RSA 鍵

RSA 鍵を生成するには、次のパラメータが必要です。

  • Tag::KEY_SIZE は、公開モジュラスのサイズをビット数で指定します。省略すると、メソッドは ErrorCode::UNSUPPORTED_KEY_SIZE を返します。サポートされる値は、1024、2048、3072、4096 です。推奨される値は、8 の倍数である鍵サイズです。
  • Tag::RSA_PUBLIC_EXPONENT は、RSA 公開指数値を指定します。省略すると、メソッドは ErrorCode::INVALID_ARGUMENT を返します。サポートされる値は、3 と 65537 です。推奨される値は、2^64 未満のすべての素数です。

次のパラメータは、RSA 鍵を生成するためには必要ありませんが、指定しないで RSA 鍵を作成すると、使用できない鍵が生成されます。ただし、これらのパラメータを省略しても、generateKey 関数はエラーを返しません。

  • Tag::PURPOSE は、許容される目的を指定します。すべての目的は、任意の組み合わせで RSA 鍵用にサポートされる必要があります。
  • Tag::DIGEST は、新しい鍵で使用できるダイジェスト アルゴリズムを指定します。一部のダイジェスト アルゴリズムをサポートしていない実装は、サポートしていないダイジェストを含む鍵生成リクエストを受け入れる必要があります。サポートしていないダイジェストは、返された鍵特性のソフトウェア適用リストに配置してください。これは、鍵が他のダイジェストで使用される場合でも、ダイジェスト処理はソフトウェア内で実行されるためです。その後、Digest::NONE でオペレーションを実行するためにハードウェアが呼び出されます。
  • Tag::PADDING は、新しい鍵で使用できるパディング モードを指定します。一部のダイジェスト アルゴリズムをサポートしていない実装は、サポートしていないダイジェスト アルゴリズムが指定された場合、鍵特性のソフトウェア適用リストに PaddingMode::RSA_PSSPaddingMode::RSA_OAEP を配置する必要があります。

ECDSA 鍵

ECDSA 鍵を生成するには、Tag::KEY_SIZE のみが必要です。これは、EC グループを選択するために使用されます。サポートされる値は 224、256、384、521 で、それぞれ NIST の p-224、p-256、p-384、p521 曲線を示します。

有用な ECDSA 鍵には Tag::DIGEST も必要ですが、鍵の生成では不要です。

AES 鍵

AES 鍵を生成するには、Tag::KEY_SIZE のみが必要です。省略すると、メソッドは ErrorCode::UNSUPPORTED_KEY_SIZE を返します。サポートされる値は 128 と 256 です。192 ビットの AES 鍵もオプションでサポートされます。

AES 鍵と関連の深いパラメータとして以下もありますが、鍵の生成では不要です。

  • Tag::BLOCK_MODE は、新しい鍵で使用できるブロックモードを指定します。
  • Tag::PADDING は、使用できるパディング モードを指定します。これは、ECB モードと CBC モードにのみ適用されます。

GCM ブロックモードが指定されている場合は、Tag::MIN_MAC_LENGTH を指定してください。省略すると、メソッドは ErrorCode::MISSING_MIN_MAC_LENGTH を返します。タグの値は、96 から 128 までの 8 の倍数を指定できます。

HMAC 鍵

HMAC 鍵の生成には次のパラメータが必要です。

  • Tag::KEY_SIZEは、鍵のサイズをビット数で指定します。64 より小さい値と 8 の倍数でない値はサポートされません。64 から 512 までのすべての 8 の倍数がサポートされます。それより大きい値がサポートされることもあります。
  • Tag::MIN_MAC_LENGTH は、この鍵で生成または検証できる MAC の最小長を指定します。値は 64 以上の 8 の倍数を指定できます。
  • Tag::DIGEST は、鍵のダイジェスト アルゴリズムを指定します。ダイジェストは 1 つだけ指定します。それ以外の場合は ErrorCode::UNSUPPORTED_DIGEST を返します。ダイジェストが Trustlet によってサポートされていない場合は、ErrorCode::UNSUPPORTED_DIGEST を返します。

鍵特性

特性引数が NULL でない場合、generateKey は、新しく生成された鍵の特性を、ハードウェア適用リストとソフトウェア適用リストに適切に振り分けて返します。どの特性がどのリストに含まれるかについては、getKeyCharacteristics をご覧ください。返される特性には、鍵生成に指定されたすべてのパラメータ(Tag::APPLICATION_IDTag::APPLICATION_DATA を除く)が含まれます。これらのタグが鍵パラメータに含まれていた場合、返される特性からそれらのタグが削除され、返された鍵 blob を調べてもそれらの値を見つけることはできなくなります。ただし、それらは暗号として鍵 blob にバインドされているため、鍵の使用時に正しい値が指定されなければ、使用は失敗します。同様に、Tag::ROOT_OF_TRUST は暗号として鍵にバインドされますが、鍵の作成時またはインポート時には指定できず、返されることはありません。

指定されたタグに加えて、Trustlet は値 KeyOrigin::GENERATED を指定して Tag::ORIGIN も追加します。また、鍵にロールバック耐性がある場合は、

Tag::ROLLBACK_RESISTANT を追加します。

ロールバック耐性

ロールバック耐性とは、セキュア ハードウェアの保証により、deleteKey または deleteAllKeys で鍵を削除すると二度と使用できなくなることです。一般的に、ロールバック耐性がない実装は、生成またはインポートされた鍵マテリアルを鍵 blob(暗号化された認証済みのフォーム)として呼び出し元に返します。キーストアが鍵 blob を削除すると鍵はなくなりますが、以前鍵マテリアルの取得に成功した攻撃者がデバイスに鍵を復元できる可能性があります。

削除された鍵を後で復元できないことをセキュア ハードウェアが保証していれば、鍵はロールバック耐性を持ちます。これは通常、攻撃者が操作できない信頼できる場所に追加の鍵メタデータを格納することで実現されます。モバイル デバイスでは、このためのメカニズムとして、リプレイ保護メモリブロック(RPMB)がよく使用されます。作成できる鍵の数は本質的に無制限であり、ロールバック耐性用の信頼できるストレージのサイズには制限があるため、新しい鍵にロールバック耐性を提供できなくても、このメソッドは成功する必要があります。その場合は、Tag::ROLLBACK_RESISTANT を鍵特性に追加しないでください。

getKeyCharacteristics

バージョン: 1、2、3

この関数は Keymaster 1 で get_key_characteristics として導入され、Keymaster 3 で改名されました。

指定された鍵に関連付けられたパラメータと承認を、ハードウェア適用とソフトウェア適用の 2 つのセットに振り分けて返します。ここでの説明は、generateKeyimportKey によって返される鍵特性リストにも同様に適用されます。

鍵の生成またはインポート時に Tag::APPLICATION_ID が指定された場合、同じ値が clientId 引数でこのメソッドに渡されます。指定されなかった場合、メソッドは ErrorCode::INVALID_KEY_BLOB を返します。同様に、鍵の生成またはインポート時に Tag::APPLICATION_DATAが指定された場合、同じ値が appData 引数でこのメソッドに渡されます。

このメソッドによって返される特性は、指定された鍵のタイプと使用方法の完全な記述となります。

特定のタグがハードウェア適用とソフトウェア適用リストのどちらに含まれるかを決定する一般的なルールとして、タグの役割がセキュア ハードウェアによって完全に保証されていれば、そのタグはハードウェア適用リストに含まれます。それ以外の場合は、ソフトウェア適用です。正確な振り分けが明確でないタグのリストを次に示します。

  • Tag::ALGORITHM Tag::KEY_SIZETag::RSA_PUBLIC_EXPONENT は、鍵に本来備わっているプロパティです。ハードウェアによって保護される鍵の場合、これらのタグはハードウェア適用リストに含まれます。
  • セキュア ハードウェアによってサポートされる Tag::DIGEST 値は、ハードウェア適用リストに配置されます。サポートされないダイジェストは、ソフトウェア適用リストに配置されます。
  • Tag::PADDING 値は、一般的にはハードウェア適用リストに配置されますが、特定のパディング モードをソフトウェアで実行しなければならない可能性がある場合は別です。その場合は、ソフトウェア適用リストに配置されます。このような可能性が生じるのは、セキュア ハードウェアでサポートされないダイジェスト アルゴリズムを使用する PSS または OAEP パディングを許可する RSA 鍵の場合です。
  • Tag::USER_SECURE_IDTag::USER_AUTH_TYPE は、ユーザー認証がハードウェアで適用される場合にのみ、ハードウェア適用に振り分けられます。これを実現するには、Keymaster の Trustlet および関連認証の Trustlet の両方がセキュアで、認証トークンの署名と検証に使用されるシークレット HMAC 鍵を共有することが必要です。詳細については、認証ページをご覧ください。
  • Tag::ACTIVE_DATETIMETag::ORIGINATION_EXPIRE_DATETIME、および Tag::USAGE_EXPIRE_DATETIME タグは、正確性を検証できる実時間へのアクセスを必要とします。ほとんどのセキュア ハードウェアは、非セキュア OS が提供する時刻情報のみにアクセスします。これは、上記のタグがソフトウェアで適用されることを意味します。
  • Tag::ORIGIN は、ハードウェアにバインドされた鍵の場合、常にハードウェア リストに配置されます。ハードウェア リストにこのタグが存在する場合、鍵がハードウェア格納型であると上位のレイヤが判断します。

importKey

バージョン: 1、2、3

この関数は Keymaster 1 で import_key として導入され、Keymaster 3 で改名されました。

鍵マテリアルを Keymaster ハードウェアにインポートします。鍵定義パラメータと出力特性は generateKey と同様に処理されますが、次の例外があります。

  • Tag::KEY_SIZETag::RSA_PUBLIC_EXPONENT(RSA 鍵のみ)は、入力パラメータでは必須ではありません。パラメータが指定されなかった場合、Trustlet は指定された鍵マテリアルから値を推定し、適切なタグと値を鍵特性に追加します。パラメータが指定された場合、Trustlet は鍵マテリアルと照合してパラメータを検証します。不一致が見つかった場合、メソッドは ErrorCode::IMPORT_PARAMETER_MISMATCH を返します。
  • 返される Tag::ORIGINKeyOrigin::IMPORTED と同じ値を持ちます。

exportKey

バージョン: 1、2、3

この関数は Keymaster 1 で export_key として導入され、Keymaster 3 で改名されました。

Keymaster の RSA または EC の鍵ペアから公開鍵をエクスポートします。

鍵の生成またはインポート時に Tag::APPLICATION_ID が指定された場合、同じ値が clientId 引数でこのメソッドに渡されます。指定されなかった場合、メソッドは ErrorCode::INVALID_KEY_BLOB を返します。同様に、鍵の生成またはインポート時に Tag::APPLICATION_DATAが指定された場合、同じ値が appData 引数でこのメソッドに渡されます。

deleteKey

バージョン: 1、2、3

この関数は Keymaster 1 で delete_key として導入され、Keymaster 3 で改名されました。

指定された鍵を削除します。このメソッドはオプションであり、ロールバック耐性を提供する KeyMaster モジュールのみが実装します。

deleteAllKeys

バージョン: 1、2、3

この関数は Keymaster 1 で delete_all_keys として導入され、Keymaster 3 で改名されました。

すべての鍵を削除します。このメソッドはオプションであり、ロールバック耐性を提供する KeyMaster モジュールのみが実装します。

destroyAttestationIds

バージョン: 3

destroyAttestationIds() メソッドは、新しい ID 構成証明機能を完全に無効にするために使用されます(新しい ID 構成証明は必須ではありませんが、強くおすすめします)。このメソッドが呼び出された後で ID 構成証明が完全に無効化されたことを TEE で確認する方法がない場合は、ID 構成証明を一切実装しないでください。その場合、このメソッドは何もせずに ErrorCode::UNIMPLEMENTED を返します。ID 構成証明がサポートされている場合は、このメソッドを実装する必要があり、このメソッドは将来のすべての ID 構成証明の試みを完全に無効にしなければなりません。このメソッドは何回でも呼び出すことができます。すでに ID 構成証明が完全に無効になっている場合、メソッドは何もせずに ErrorCode::OK を返します。

このメソッドが返すエラーコードは、ErrorCode::UNIMPLEMENTED(ID 構成証明がサポートされていない場合)、ErrorCode:OKErrorCode::KEYMASTER_NOT_CONFIGURED、またはセキュア ハードウェアとの通信に失敗したことを示すエラーコードのいずれかです。

begin

バージョン: 1、2、3

指定された鍵で、指定された目的のために、指定されたパラメータを(必要に応じて)使用して暗号オペレーションを開始し、updatefinish でオペレーションを完了するために使用されるオペレーション ハンドルを返します。オペレーション ハンドルは、認証済みオペレーションの「チャレンジ」トークンとしても使用され、そうしたオペレーションのために認証トークンの challenge フィールドに格納されます。

Keymaster 実装は、少なくとも 16 個の同時実行オペレーションをサポートします。キーストアは最大 15 個の同時実行オペレーションを使用し、1 つはパスワード暗号化で使用するために void として取って置きます。キーストアで 15 個のオペレーションが実行されている(begin は呼び出し済みだが finish または abort はまだ呼び出されていない)ときに、キーストアが 16 番目のオペレーションを開始するリクエストを受信すると、有効なオペレーションの数を 14 に減らすために、最後に使用されたオペレーションで abort を呼び出した後、begin を呼び出して新たにリクエストされたオペレーションを開始します。

鍵の生成またはインポート時に Tag::APPLICATION_ID または Tag::APPLICATION_DATA が指定された場合、begin の呼び出しには、このメソッドに対する inParams 引数で最初に指定された値を持つそれらのタグが挿入されます。

承認の適用

このメソッドの実行時には、次の鍵承認が Trustlet によって適用されます(実装が該当の鍵承認を「ハードウェア適用」特性に振り分け、オペレーションが公開鍵オペレーションでない場合)。RSA 鍵または EC 鍵の公開鍵オペレーション(つまり、KeyPurpose::ENCRYPTKeyPurpose::VERIFY)は、承認要件が満たされなくても成功します。

  • Tag::PURPOSE: begin() 呼び出しで指定された目的は、リクエストされたオペレーションが公開鍵オペレーションでない限り、鍵承認の目的の 1 つと一致しなければなりません。指定された目的が一致せず、オペレーションが公開鍵オペレーションでない場合、beginErrorCode::UNSUPPORTED_PURPOSE を返します。公開鍵オペレーションは、非対称暗号化オペレーションまたは検証オペレーションです。
  • Tag::ACTIVE_DATETIME は、信頼できる UTC タイムソースが利用可能な場合にのみ適用できます。現在の日時がタグ値より前である場合、メソッドは ErrorCode::KEY_NOT_YET_VALID を返します。
  • Tag::ORIGINATION_EXPIRE_DATETIME は、信頼できる UTC タイムソースが利用可能な場合にのみ適用できます。現在の日時がタグ値より後で、目的が KeyPurpose::ENCRYPT または KeyPurpose::SIGN である場合、メソッドは ErrorCode::KEY_EXPIRED を返します。
  • Tag::USAGE_EXPIRE_DATETIME は、信頼できる UTC タイムソースが利用可能な場合にのみ適用できます。現在の日時がタグ値より後で、目的が KeyPurpose::DECRYPT または KeyPurpose::VERIFY である場合、メソッドは ErrorCode::KEY_EXPIRED を返します。
  • Tag::MIN_SECONDS_BETWEEN_OPS は、鍵の最後の使用を示す信頼できる相対タイマーと比較されます。最後の使用時刻にタグ値を加算した値が現在の時刻に達しない場合、メソッドは ErrorCode::KEY_RATE_LIMIT_EXCEEDED を返します。重要な実装の詳細については、タグの説明をご覧ください。
  • Tag::MAX_USES_PER_BOOT は、起動時刻以降の鍵の使用をトラッキングするセキュア カウンタと比較されます。これ以前の使用回数がタグ値を超えている場合、メソッドは ErrorCode::KEY_MAX_OPS_EXCEEDED を返します。
  • Tag::USER_SECURE_ID は、鍵に Tag::AUTH_TIMEOUT も含まれている場合にのみ、このメソッドによって適用されます。鍵に両方が指定されている場合、このメソッドは有効な Tag::AUTH_TOKENinParams で受け取る必要があります。認証トークンが有効であるためには、以下の条件がすべて満たされる必要があります。
    • HMAC フィールドが正しく検証される。
    • 鍵の Tag::USER_SECURE_ID 値の少なくとも 1 つが、トークンのセキュア ID 値の少なくとも 1 つと一致する。
    • トークンの認証タイプと一致する Tag::USER_AUTH_TYPE が鍵に含まれている。

    上記の条件のいずれかが満たされない場合、メソッドは ErrorCode::KEY_USER_NOT_AUTHENTICATED を返します。

  • Tag::CALLER_NONCE は、呼び出し元がノンスまたは初期化ベクトル(IV)を指定することを可能にします。鍵にこのタグがないにもかかわらず、呼び出し元がこのメソッドに Tag::NONCE を渡した場合は、ErrorCode::CALLER_NONCE_PROHIBITED が返されます。
  • Tag::BOOTLOADER_ONLY は、ブートローダーのみが鍵を使用できることを指定します。ブートローダーの実行が完了した後で、このメソッドがブートローダー専用の鍵で呼び出された場合は、ErrorCode::INVALID_KEY_BLOB を返します。

RSA 鍵

すべての RSA 鍵オペレーションでは、inParams でパディング モードを 1 つだけ指定します。指定しなかった場合または 2 つ以上指定した場合、メソッドは ErrorCode::UNSUPPORTED_PADDING_MODE を返します。

RSA の署名および検証オペレーションにはダイジェストが必要であり、OAEP パディング モードを使用する RSA の暗号化および復号オペレーションでも同様です。その場合、呼び出し元は inParams でダイジェストを 1 つだけ指定します。指定しなかった場合または 2 つ以上指定した場合、メソッドは ErrorCode::UNSUPPORTED_DIGEST を返します。

秘密鍵オペレーション(KeyPurpose::DECYPTKeyPurpose::SIGN)では、ダイジェストとパディングの承認が必要です。つまり、指定された値が鍵承認に含まれている必要があります。含まれていないと、メソッドは状況に応じて ErrorCode::INCOMPATIBLE_DIGEST または ErrorCode::INCOMPATIBLE_PADDING を返します。公開鍵オペレーション(KeyPurpose::ENCRYPTKeyPurpose::VERIFY)は、承認されていないダイジェストまたはパディングでも許可されます。

PaddingMode::NONE を除いて、すべての RSA パディング モードは特定の目的にのみ適用されます。具体的には、PaddingMode::RSA_PKCS1_1_5_SIGNPaddingMode::RSA_PSS は署名と検証のみをサポートし、PaddingMode::RSA_PKCS1_1_1_5_ENCRYPTPaddingMode::RSA_OAEP は暗号化と復号のみをサポートします。このメソッドは、指定されたモードが指定された目的をサポートしていない場合、ErrorCode::UNSUPPORTED_PADDING_MODE を返します。

パディング モードとダイジェストの間には、次のような重要な相互関係があります。

  • PaddingMode::NONE は「未処理の」RSA オペレーションが実行されることを示します。署名または検証では、ダイジェストに Digest::NONE が指定されます。パディングなしの暗号化または復号では、ダイジェストは不要です。
  • PaddingMode::RSA_PKCS1_1_5_SIGN パディングにはダイジェストが必要です。ダイジェストには Digest::NONE を指定できます。その場合、Keymaster 実装は、DigestInfo 構造を追加できないため、適切な PKCS#1 v1.5 署名構造をビルドできません。その代わり、実装は 0x00 || 0x01 || PS || 0x00 || M を構築します。M は指定されたメッセージ、PS はパディング文字列です。RSA 鍵のサイズはメッセージより 11 バイト以上大きくなければなりません。そうでない場合、メソッドは ErrorCode::INVALID_INPUT_LENGTH を返します。
  • PaddingMode::RSA_PKCS1_1_1_5_ENCRYPT パディングにはダイジェストは不要です。
  • PaddingMode::RSA_PSS パディングには、Digest::NONE 以外のダイジェストが必要です。Digest::NONE が指定された場合、メソッドは ErrorCode::INCOMPATIBLE_DIGEST を返します。さらに、RSA 鍵のサイズは、ダイジェストの出力サイズより 2 + D バイト以上大きくなければなりません。D はダイジェストのサイズ(バイト数)です。そうでない場合、メソッドは ErrorCode::INCOMPATIBLE_DIGEST を返します。ソルトサイズは D です。
  • PaddingMode::RSA_OAEP パディングには、Digest::NONE 以外のダイジェストが必要です。Digest::NONE が指定された場合、メソッドは ErrorCode::INCOMPATIBLE_DIGEST を返します。

EC 鍵

EC 鍵オペレーションでは、inParams でパディング モードを 1 つだけ指定します。指定しなかった場合または 2 つ以上指定した場合、メソッドは ErrorCode::UNSUPPORTED_PADDING_MODE を返します。

秘密鍵オペレーション(KeyPurpose::SIGN)では、ダイジェストとパディングの承認が必要です。つまり、指定された値が鍵承認に含まれている必要があります。含まれていない場合は、ErrorCode::INCOMPATIBLE_DIGEST を返します。公開鍵オペレーション(KeyPurpose::VERIFY)は、承認されていないダイジェストまたはパディングでも許可されます。

AES 鍵

AES 鍵オペレーションでは、inParams でブロックモードとパディング モードをそれぞれ 1 つだけ指定します。いずれかを指定しなかった場合または 2 つ以上指定した場合は、ErrorCode::UNSUPPORTED_BLOCK_MODE または ErrorCode::UNSUPPORTED_PADDING_MODE を返します。指定されたモードは鍵によって承認される必要があります。承認されない場合、メソッドは ErrorCode::INCOMPATIBLE_BLOCK_MODE または ErrorCode::INCOMPATIBLE_PADDING_MODE を返します。

ブロックモードが BlockMode::GCM の場合、inParams には Tag::MAC_LENGTH を指定します。指定する値は、128 以下または鍵承認の Tag::MIN_MAC_LENGTH 値以上の 8 の倍数です。MAC 長が 128 より大きい場合または 8 の倍数でない場合は、ErrorCode::UNSUPPORTED_MAC_LENGTH を返します。値が鍵の最小長より小さい場合は、ErrorCode::INVALID_MAC_LENGTH を返します。

ブロックモードが BlockMode::GCM または BlockMode::CTR の場合、指定されるパディング モードは PaddingMode::NONE でなければなりません。BlockMode::ECB または BlockMode::CBC の場合、パディング モードとして PaddingMode::NONE または PaddingMode::PKCS7 を指定できます。パディング モードがこれらの条件を満たしていない場合は、ErrorCode::INCOMPATIBLE_PADDING_MODE を返します。

ブロックモードが BlockMode::CBCBlockMode::CTRBlockMode::GCM のいずれかの場合、初期化ベクトルまたはノンスが必要です。ほとんどの場合、呼び出し元は IV またはノンスを提供しません。その場合、Keymaster 実装はランダムな IV またはノンスを生成し、outParamsTag::NONCE を介してそれらを返します。CBC と CTR の IV は 16 バイトです。GCM のノンスは 12 バイトです。鍵承認に Tag::CALLER_NONCE が含まれる場合、呼び出し元は inParamsTag::NONCE を介して IV またはノンスを提供できます。Tag::CALLER_NONCE が承認されておらず、ノンスが提供された場合は、ErrorCode::CALLER_NONCE_PROHIBITED を返します。Tag::CALLER_NONCE が承認されておらず、ノンスが提供されない場合は、ランダムな IV / ノンスを生成します。

HMAC 鍵

HMAC 鍵オペレーションでは、inParamsTag::MAC_LENGTH を指定します。指定する値は、ダイジェストの長さ以下か、鍵承認の Tag::MIN_MAC_LENGTH 値以上の 8 の倍数でなければなりません。MAC 長がダイジェストの長さより大きい場合または 8 の倍数でない場合は、ErrorCode::UNSUPPORTED_MAC_LENGTH を返します。値が鍵の最小長より小さい場合は、ErrorCode::INVALID_MAC_LENGTH を返します。

update

バージョン: 1、2、3

begin で開始された進行中のオペレーションで処理されるデータを提供します。オペレーションは、operationHandle パラメータで指定されます。

バッファ処理の柔軟性を高めるために、このメソッドの実装には、提供されたデータ量より消費するデータ量を少なくするオプションがあります。呼び出し元は、以降の呼び出しで残りのデータをフィードするためのループ処理を行います。消費された入力の量は、inputConsumed パラメータで返されます。オペレーションが提供を受け入れられなくなるまで、実装は常に少なくとも 1 バイトを消費します。0 バイトを超える提供に対して消費が 0 バイトである場合、呼び出し元はこれをエラーと見なしてオペレーションを中止します。

実装では、update の結果として返すデータの量も選択できます。これは、暗号化と復号のオペレーションにのみ関係します。署名と検証では、finish までデータが返されないからです。データをバッファリングせず、できるだけ早く返してください。

エラー処理

このメソッドが ErrorCode::OK 以外のエラーコードを返すと、オペレーションは中止され、オペレーション ハンドルは無効化されます。その後、ハンドルを update、finish、または abort メソッドで使用すると、ErrorCode::INVALID_OPERATION_HANDLE が返されます。

承認の適用

鍵承認の適用は、主として begin で行われます。ただし、次の場合は例外です。

この場合、鍵はオペレーションごとに承認を必要とし、update メソッドは Tag::AUTH_TOKENinParams 引数で受け取ります。HMAC は、トークンが有効であること、一致するセキュア ユーザー ID を保持していること、鍵の Tag::USER_AUTH_TYPE と一致すること、現在のオペレーションのオペレーション ハンドルを challenge フィールドに格納していることを検証します。これらの条件が満たされない場合は、ErrorCode::KEY_USER_NOT_AUTHENTICATED が返されます。

呼び出し元は、updatefinish のすべての呼び出しに対して認証トークンを提供します。実装では、必要に応じて一度だけトークンを検証する必要があります。

RSA 鍵

Digest::NONE を使用する署名および検証オペレーションの場合、このメソッドは、一度の更新で、署名または検証するブロック全体を受け入れます。ブロックの一部のみを消費することはできません。ただし、呼び出し元が複数の更新でデータを提供することを選択した場合、このメソッドはそれを受け入れます。呼び出し元が提供する署名用のデータが使用可能な量を超えている場合(データ長が RSA 鍵サイズを超える場合)は、ErrorCode::INVALID_INPUT_LENGTH を返します。

ECDSA 鍵

Digest::NONE を使用する署名および検証オペレーションの場合、このメソッドは、一度の更新で、署名または検証するブロック全体を受け入れます。ブロックの一部のみを消費することはできません。

ただし、呼び出し元が複数の更新でデータを提供することを選択した場合、このメソッドはそれを受け入れます。呼び出し元が提供する署名用のデータが使用可能な量を超えている場合は、データが暗黙的に切り捨てられます(この超過データの処理は、RSA オペレーションにおける同様の場合とは異なります。これは、古いクライアントとの互換性を維持するためです)。

AES 鍵

AES GCM モードは、inParams 引数で Tag::ASSOCIATED_DATA タグを介して提供される「関連認証データ」をサポートします。関連データは反復呼び出しで提供できます(これはデータが大きすぎて単一ブロックでは送信できない場合に重要です)が、暗号化または復号されるデータに常に先行します。1 つの update 呼び出しは関連データと暗号化 / 復号されるデータの両方を受け取りますが、後続の update に関連データを含めることはできません。呼び出し元が、暗号化 / 復号されるデータを含む呼び出しの後で、関連データを update 呼び出しに渡すと、ErrorCode::INVALID_TAG が返されます。

GCM 暗号化では、finish によってタグが暗号テキストの末尾に付加されます。復号の際、最後の update 呼び出しに渡されたデータの最後の Tag::MAC_LENGTH バイトはタグになります。update の特定の呼び出しは、それが最後の呼び出しかどうかを知ることができないため、finish の際にタグの長さ以外のすべてのデータを処理し、タグの可能性があるデータをバッファリングします。

finish

バージョン: 1、2、3

begin で開始された進行中のオペレーションを終了し、1 つまたは複数の update によって提供された未処理のデータをすべて処理します。

このメソッドはオペレーションの最後に呼び出されます。したがって、処理されたすべてのデータが返されます。

このメソッドは、正常に完了するかエラーを返すかのいずれかを行ってオペレーションを完了し、その結果、指定されたオペレーション ハンドルを無効化します。その後、ハンドルを finish、update、または abort メソッドで使用すると、ErrorCode::INVALID_OPERATION_HANDLE が返されます。

署名オペレーションは出力として署名を返します。検証オペレーションは signature パラメータで署名を受け入れ、出力を返しません。

承認の適用

鍵承認の適用は、主として begin で行われます。ただし、次の場合は例外です。

この場合、鍵はオペレーションごとに承認を必要とし、update メソッドは Tag::AUTH_TOKENinParams 引数で受け取ります。HMAC は、トークンが有効であること、一致するセキュア ユーザー ID を保持していること、鍵の Tag::USER_AUTH_TYPE と一致すること、現在のオペレーションのオペレーション ハンドルを challenge フィールドに格納していることを検証します。これらの条件が満たされない場合は、ErrorCode::KEY_USER_NOT_AUTHENTICATED が返されます。

呼び出し元は、updatefinish のすべての呼び出しに対して認証トークンを提供します。実装では、必要に応じて一度だけトークンを検証する必要があります。

RSA 鍵

追加要件の一部は、パディング モードによって異なります。

  • PaddingMode::NONE。パディングなしの署名および暗号化オペレーションでは、指定されたデータの長さが鍵より小さい場合、署名 / 暗号の前にデータの左にゼロがパディングされます。データが鍵と同じ長さで数値が大きい場合は、ErrorCode::INVALID_ARGUMENT を返します。検証および復号オペレーションでは、データの長さは鍵と正確に同じでなければなりません。同じでない場合は、ErrorCode::INVALID_INPUT_LENGTH. を返します。
  • PaddingMode::RSA_PSS。PSS パディングを使用する署名オペレーションでは、PSS ソルトは 20 バイト以上の長さで、ランダムに生成されます。ソルトはかなり長くなる可能性があります。リファレンス実装は、最大サイズのソルトを使用します。begininputParamsTag::DIGEST によって指定されたダイジェストが PSS ダイジェスト アルゴリズムとして使用され、SHA1 が MGF1 ダイジェスト アルゴリズムとして使用されます。
  • PaddingMode::RSA_OAEPbegininputParamsTag::DIGEST によって指定されたダイジェストが OAEP ダイジェスト アルゴリズムとして使用され、SHA1 が MGF1 ダイジェスト アルゴリズムとして使用されます。

ECDSA 鍵

パディングなしの署名または検証用に提供されたデータが長すぎる場合は、切り捨てます。

AES 鍵

追加要件の一部は、ブロックモードによって異なります。

  • BlockMode::ECB または BlockMode::CBC。パディングが PaddingMode::NONE でデータ長が AES ブロックサイズの倍数でない場合は、ErrorCode::INVALID_INPUT_LENGTH を返します。パディングが PaddingMode::PKCS7 の場合は、PKCS#7 仕様に従ってデータをパディングします。PKCS#7 では、データがブロック長の倍数の場合、追加のパディング ブロックを追加することが推奨されます。
  • BlockMode::GCM。暗号化の際は、すべての平文を処理した後でタグ(Tag::MAC_LENGTH バイト)を計算し、返される暗号テキストの末尾に付加します。復号の際は、最後の Tag::MAC_LENGTH バイトをタグとして処理します。タグの検証に失敗した場合は、ErrorCode::VERIFICATION_FAILED を返します。

abort

バージョン: 1、2、3

進行中のオペレーションを中止します。abort 呼び出しの後、指定されたオペレーション ハンドルを updatefinish、または abort で使用すると、ErrorCode::INVALID_OPERATION_HANDLE が返されます。

get_supported_algorithms

バージョン: 1

Keymaster ハードウェア実装がサポートするアルゴリズムのリストを返します。ソフトウェア実装は空のリストを返します。ハイブリッド実装は、ハードウェアがサポートするアルゴリズムのみのリストを返します。

Keymaster 1 実装は、RSA、EC、AES、HMAC をサポートします。

get_supported_block_modes

バージョン: 1

指定されたアルゴリズムと目的に対して Keymaster ハードウェア実装がサポートする AES ブロックモードのリストを返します。

ブロック暗号ではない RSA、EC、HMAC の場合、すべての有効な目的に対して空のリストを返します。無効な目的に対しては ErrorCode::INVALID_PURPOSE を返します。

Keymaster 1 実装は、AES の暗号化および復号について、ECB、CBC、CTR、GCM をサポートします。

get_supported_padding_modes

バージョン: 1

指定されたアルゴリズムと目的に対して Keymaster ハードウェア実装がサポートするパディング モードのリストを返します。

HMAC と EC にはパディングの概念がないため、すべての有効な目的に対して空のリストを返します。無効な目的に対しては ErrorCode::INVALID_PURPOSE を返します。

RSA の場合、Keymaster 1 実装は以下をサポートします。

  • パディングなしの暗号化、復号、署名、検証。パディングなしの暗号化と署名では、メッセージが公開モジュラスより短い場合、実装で左にゼロをパディングする必要があります。パディングなしの復号と検証では、入力の長さが公開モジュラスのサイズと一致する必要があります。
  • PKCS#1 v1.5 暗号化と署名のパディング モード
  • 最小のソルト長が 20 の PSS
  • OAEP

ECB モードと CBC モードの AES では、Keymaster 1 実装はパディングなしと PKCS#7 パディングをサポートしません。CTR モードと GCM モードでは、パディングなしのみをサポートします。

get_supported_digests

バージョン: 1

指定されたアルゴリズムと目的に対して Keymaster ハードウェア実装がサポートするダイジェスト モードのリストを返します。

AES モードではダイジェストが不要でありサポートされないため、有効な目的に対して空のリストを返します。

Keymaster 1 実装では、定義されたダイジェストのサブセットを実装できます。実装は SHA-256 を提供します。また、MD5、SHA1、SHA-224、SHA-256、SHA384、SHA512(定義されたダイジェストの完全なセット)も提供できます。

get_supported_import_formats

バージョン: 1

指定されたアルゴリズムの Keymaster ハードウェア実装がサポートするインポート形式のリストを返します。

Keymaster 1 実装は、RSA および EC 鍵ペアをインポートするための PKCS#8 形式(パスワード保護なし)をサポートし、AES および HMAC 鍵マテリアルの未処理のインポートをサポートします。

get_supported_export_formats

バージョン: 1

指定されたアルゴリズムの Keymaster ハードウェア実装がサポートするエクスポート形式のリストを返します。

Keymaster 1 実装は、RSA および EC 公開鍵をエクスポートするための X.509 形式をサポートします。秘密鍵または非対称鍵のエクスポートはサポートされません。

過去に使用されていた関数

Keymaster 0

以下は、最初の Keymaster 0 の定義に含まれていた関数です。これらは Keymaster 1 の構造体 keymaster1_device_t 内にありました。しかし、Keymaster 1.0 では実装されず、関数ポインタは NULL に設定されました。

  • generate_keypair
  • import_keypair
  • get_keypair_public
  • delete_keypair
  • delete_all
  • sign_data
  • Verify_data

Keymaster 1

以下は、Keymaster 1 の定義に含まれていた関数です。これらは、Keymaster 2 で上記の Keymaster 0 関数とともに削除されました。

  • get_supported_algorithms
  • get_supported_block_modes
  • get_supported_padding_modes
  • get_supported_digests
  • get_supported_import_formats
  • get_supported_export_formats

Keymaster 2

以下は、Keymaster 2 の定義に含まれていた関数です。これらは、Keymaster 3 で上記の Keymaster 1 関数とともに削除されました。

  • configure