./VtsHalKeymasterV4_0TargetTest --gtest_filter=PerInstance/AttestationTest.RsaAttestation/0_default
エラー1:
hardware/interfaces/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp:364: Failure 期待される値は一致しません: ErrorCode::OK これは: OK error これは: UNKNOWN_ERROR
hardware/interfaces/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp:4305: Failure 以下が真である必要があります: verify_attestation_record("challenge", "foo", key_characteristics_.softwareEnforced, key_characteristics_.hardwareEnforced, SecLevel(), cert_chain[0]) 実際の値: false 期待される値: true
[VTSテスト結果] PerInstance/AttestationTest.RsaAttestation/0_default (17408 ms)
コード解析:
bool verify_attestation_record(const std::string& challenge, const std::string& app_id,
AuthorizationSet expected_sw_enforced,
AuthorizationSet expected_hw_enforced, SecurityLevel security_level,
const hidl_vec<uint8_t>& attestation_cert) {
X509_Ptr cert(parse_cert_blob(attestation_cert));
if (!cert.get()) return false;
ASN1_OCTET_STRING* attest_rec = get_attestation_record(cert.get());
if (!attest_rec) return false;
AuthorizationSet att_sw_enforced;
AuthorizationSet att_hw_enforced;
uint32_t att_attestation_version;
uint32_t att_keymaster_version;
SecurityLevel att_attestation_security_level;
SecurityLevel att_keymaster_security_level;
HidlBuf att_challenge;
HidlBuf att_unique_id;
HidlBuf att_app_id;
ALOGD("1. verify_attestation_record ==> parse_attestation_record");
auto error = parse_attestation_record(attest_rec->data, attest_rec->length,
&att_attestation_version,
&att_attestation_security_level,
&att_keymaster_version,
&att_keymaster_security_level,
&att_challenge,
&att_sw_enforced,
&att_hw_enforced,
&att_unique_id);
if (error != ErrorCode::OK) {
ALOGE("parse_attestation_record failed error: %d", error);
return false;
}
EXPECT_GE(att_attestation_version, 3U);
// 省略
}
ログ出力により、d2i_KM_KEY_DESCRIPTIONで異常が発生していることが判明しました。具体的なログは以下の通りです。
13039 02-06 07:15:54.187 3140 3140 D keymaster_hidl_hal_test: 3. RsaAttestation => verify_attestation_record 13040 02-06 07:15:54.240 3140 3140 D keymaster_hidl_hal_test: 1. verify_attestation_record => parse_attestation_record
関連するデータ:
30 81 a8 02 01 02 0a 01 01 02 01 03 0a 01 01 04 09 63 68 61 6c 6c 65 6e 67 65 04 00 30 12 bf 85 ...
解析結果: RootOfTrust(ROT)に不整合が見つかりました。具体的には、ROT内の要素数が不足しています。
TAでの修正:
static int asn1_write_rot(int verified_boot, unsigned char **p, size_t *len) {
int len_ret = 0;
unsigned char buf[ASN1_BUF_LEN_DEFAULT];
unsigned char *ptr = buf + sizeof(buf);
unsigned char *start = buf;
root_of_trust_info_t device_rot;
memset(&device_rot, 0, sizeof(root_of_trust_info_t));
TEE_Result res = get_device_rot(&device_rot);
DMSG("get_device_rot result:%d \n", res);
MBEDTLS_ASN1_CHK_ADD(len_ret, mbedtls_asn1_write_octet_string(&ptr, start,
device_rot.vbmeta_digest,
sizeof(device_rot.vbmeta_digest)));
MBEDTLS_ASN1_CHK_ADD(len_ret, mbedtls_asn1_write_bool(&ptr, start, device_rot.devcelock_state));
MBEDTLS_ASN1_CHK_ADD(len_ret, mbedtls_asn1_write_enum(&ptr, start, verified_boot));
// 新しいOCTET_STRINGを追加
MBEDTLS_ASN1_CHK_ADD(len_ret, mbedtls_asn1_write_octet_string(&ptr, start,
device_rot.verified_boot_key,
sizeof(device_rot.verified_boot_key)));
MBEDTLS_ASN1_CHK_ADD(len_ret, mbedtls_asn1_write_len(&ptr, start, (size_t)len_ret));
MBEDTLS_ASN1_CHK_ADD(len_ret, mbedtls_asn1_write_tag(&ptr, start,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE));
if (!*p) {
*p = TEE_Malloc((uint32_t)len_ret, TEE_MALLOC_FILL_ZERO);
}
if (!*p) {
EMSG("Can not populate non-allocated buffer");
return -1;
}
TEE_MemMove(*p, ptr, (uint32_t)len_ret);
*len = (size_t)len_ret;
return 0;
}
この修正により、テスト結果は改善されましたが、新たな問題が発生しました。
エラー2:
device_locked状態とverified_boot_stateが一致していません。具体的なテストコードは次の通りです。
EXPECT_NE(property_get("ro.boot.vbmeta.device_state", property_value, ""), 0);
if (!strcmp(property_value, "unlocked")) {
EXPECT_FALSE(device_locked);
} else {
EXPECT_TRUE(device_locked);
}
EXPECT_NE(property_get("ro.boot.verifiedbootstate", property_value, ""), 0);
if (!strcmp(property_value, "orange")) {
EXPECT_EQ(verified_boot_state, KM_VERIFIED_BOOT_UNVERIFIED);
EXPECT_EQ(0, memcmp(verified_boot_key.data(), empty_boot_key.data(), verified_boot_key.size()));
}
デバイスプロパティ値:
[ro.boot.vbmeta.device_state]: [unlocked]
[ro.debuggable]: [1]
[ro.boot.verifiedbootstate]: [orange]
TAでのログ出力結果:
0818 D/TA: asn1_write_rot:1569 device_locked = 1
0823 D/TA: asn1_write_rot:1583 input verified_boot = 0, rot verified boot state = 2
最終的に、verified_boot_keyが空文字列であることを確認し、TAのロジックを再調整しました。
エラー4:
keymasterバージョンとアテステーションバージョンの不一致が原因でした。
TA側の定義を次のように変更しました。
#define KEYMASTER_VERSION 4
#define ATTESTATION_VERSION 3
これにより、すべてのテストが正常に通過しました。
[OK] PerInstance/AttestationTest.RsaAttestation/0_default (16978 ms)
まとめ:
主な課題は、初期の解析段階でデータ構造の不一致を特定することに時間がかかりました。特に、boringsslのログ出力やROT情報の取得部分での差異が原因でした。