Keymaster HAL VTSテストにおけるRSAアテステーションエラーの解析と修正

./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情報の取得部分での差異が原因でした。

タグ: Android Keymaster VTS

6月10日 19:05 投稿