問題の発生とログ解析
VTS(Vendor Test Suite)テスト実行中に、以下のコマンドで特定のテストケースが失敗しました。
# ./VtsHalKeymasterV4_0TargetTest --gtest_filter=PerInstance/SigningOperationsTest.RsaUseRequiresCorrectAppIdAppData/0_default
テスト結果の出力から、次の3つのアサーションが期待通りに失敗していることが確認できます:
Begin(KeyPurpose::SIGN, 空のAuthorizationSet)→ 実際はOKだが、INVALID_KEY_BLOBが期待されているBegin(... TAG_APPLICATION_IDのみ指定)→ 同様にOKで返っており不正Begin(... TAG_APPLICATION_DATAのみ指定)→ これも同様に通過してしまっている
これらの結果は、鍵生成時に設定されたTAG_APPLICATION_IDおよびTAG_APPLICATION_DATAの照合が正しく行われていないことを示しています。
テストコードの詳細
該当するテスト関数はRSA鍵の使用時において、アプリケーション固有の識別情報が正確に一致するかを検証する目的で設計されています。
TEST_P(SigningOperationsTest, RsaUseRequiresCorrectAppIdAppData) {
// RSA鍵を生成(clientid, appdata を含む)
ASSERT_EQ(ErrorCode::OK,
GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.RsaSigningKey(2048, 65537)
.Digest(Digest::NONE)
.Padding(PaddingMode::NONE)
.Authorization(TAG_APPLICATION_ID, HidlBuf("clientid"))
.Authorization(TAG_APPLICATION_DATA, HidlBuf("appdata"))));
// 条件不足:何も指定しない → INVALID_KEY_BLOB が期待される
EXPECT_EQ(ErrorCode::INVALID_KEY_BLOB,
Begin(KeyPurpose::SIGN,
AuthorizationSetBuilder().Digest(Digest::NONE).Padding(PaddingMode::NONE)));
AbortIfNeeded();
// client_id のみ指定 → 不完全なため無効
EXPECT_EQ(ErrorCode::INVALID_KEY_BLOB,
Begin(KeyPurpose::SIGN,
AuthorizationSetBuilder()
.Digest(Digest::NONE)
.Padding(PaddingMode::NONE)
.Authorization(TAG_APPLICATION_ID, HidlBuf("clientid"))));
AbortIfNeeded();
// app_data のみ指定 → 同様に無効
EXPECT_EQ(ErrorCode::INVALID_KEY_BLOB,
Begin(KeyPurpose::SIGN,
AuthorizationSetBuilder()
.Digest(Digest::NONE)
.Padding(PaddingMode::NONE)
.Authorization(TAG_APPLICATION_DATA, HidlBuf("appdata"))));
AbortIfNeeded();
// 正しい組み合わせ:両方揃っている場合のみ許可
EXPECT_EQ(ErrorCode::OK,
Begin(KeyPurpose::SIGN,
AuthorizationSetBuilder()
.Digest(Digest::NONE)
.Padding(PaddingMode::NONE)
.Authorization(TAG_APPLICATION_DATA, HidlBuf("appdata"))
.Authorization(TAG_APPLICATION_ID, HidlBuf("clientid"))));
}
根本原因の特定
この問題はTrustZone側(TA: Trusted Application)のTA_check_params関数内での検証ロジックに起因していました。特に、操作目的(op_purpose)がKM_PURPOSE_SIGNの場合において、TAG_APPLICATION_IDやTAG_APPLICATION_DATAの存在と内容の整合性が適切にチェックされていませんでした。
修正後のロジック
以下の条件分岐を追加することで、必要なタグが不足しているか、値が一致しない場合にエラーを返すように変更しました。
out_cp:
if (op_purpose == KM_PURPOSE_SIGN &&
((!client_id_match && client_id_required) ||
(!app_data_match && app_data_required))) {
EMSG("Application identifier mismatch or missing");
res = KM_ERROR_INVALID_KEY_BLOB;
}
return res;
ここで、client_id_matchおよびapp_data_matchは、提供されたパラメータセットとキーボール内部に格納された値との比較結果を表します。requiredフラグは、鍵生成時にこれらのタグが含まれていたかどうかを示します。
修正後のテスト結果
上記の修正を適用後、再びテストを実行したところ、すべてのチェックが正常にパスしました。
[ RUN ] PerInstance/SigningOperationsTest.RsaUseRequiresCorrectAppIdAppData/0_default
[ OK ] PerInstance/SigningOperationsTest.RsaUseRequiresCorrectAppIdAppData/0_default (8597 ms)
これは、アプリケーション識別情報に関するセキュリティポリシーが正しく実装され、想定通りの振る舞いをしていることを確認できたことを意味します。