optee km4.0 VTS: PerInstance/AttestationTest.RsaAttestation/0_default failed

./VtsHalKeymasterV4_0TargetTest --gtest_filter=PerInstance/AttestationTest.RsaAttestation/0_default

异常1:

hardware/interfaces/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp:364: Failure
Expected equality of these values:
ErrorCode::OK
Which is: OK
error
Which is: UNKNOWN_ERROR
hardware/interfaces/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp:4305: Failure
Value of: verify_attestation_record("challenge", "foo", key_characteristics_.softwareEnforced, key_characteristics_.hardwareEnforced, SecLevel(), cert_chain[0])
Actual: false
Expected: true
[ FAILED ] PerInstance/AttestationTest.RsaAttestation/0_default, where GetParam() = "default" (17408 ms)
[----------] 1 test from PerInstance/AttestationTest (17408 ms total)

[----------] Global test environment tear-down
[==========] 1 test from 1 test suite ran. (17410 ms total)
[ PASSED ] 0 tests.
[ FAILED ] 1 test, listed below:
[ FAILED ] PerInstance/AttestationTest.RsaAttestation/0_default, where GetParam() = "default"

1 FAILED TEST

代码排查

bool verify_attestation_record(const string& challenge, const 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));
    EXPECT_TRUE(!!cert.get());
    if (!cert.get()) return false;

    ASN1_OCTET_STRING* attest_rec = get_attestation_record(cert.get());
    EXPECT_TRUE(!!attest_rec);
    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);
    EXPECT_EQ(ErrorCode::OK, error);
    if (error != ErrorCode::OK) {
		ALOGE("parse_attestation_record failed error: %d", error);
		return false;
    }

    EXPECT_GE(att_attestation_version, 3U);

    //以下省略
}

 

通过增加log,发现异常点在d2i_KM_KEY_DESCRIPTION,log如下:

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
13041 02-06 07:15:54.240 3140 3140 D keymaster_4_attestation_record_cpp: parse_attestation_record enter
13042 02-06 07:15:54.240 3140 3140 D keymaster_4_attestation_record_cpp: ==dump asn1_key_desc start, size = 171
13043 02-06 07:15:54.240 3140 3140 D keymaster_4_attestation_record_cpp: dumpData data_len : 171
13044 02-06 07:15:54.240 3140 3140 D keymaster_4_attestation_record_cpp: [000] 30 81 a8 02 01 02 0a 01 01 02 01 03 0a 01 01 04
13045 02-06 07:15:54.240 3140 3140 D keymaster_4_attestation_record_cpp: [001] 09 63 68 61 6c 6c 65 6e 67 65 04 00 30 12 bf 85
13046 02-06 07:15:54.240 3140 3140 D keymaster_4_attestation_record_cpp: [002] 3d 05 02 03 02 28 e2 bf 85 45 05 04 03 66 6f 6f
13047 02-06 07:15:54.240 3140 3140 D keymaster_4_attestation_record_cpp: [003] 30 79 a1 08 31 06 02 01 02 02 01 03 a2 03 02 01
13048 02-06 07:15:54.240 3140 3140 D keymaster_4_attestation_record_cpp: [004] 01 a3 04 02 02 08 00 a5 05 31 03 02 01 04 a6 05
13049 02-06 07:15:54.240 3140 3140 D keymaster_4_attestation_record_cpp: [005] 31 03 02 01 05 bf 81 48 05 02 03 01 00 01 bf 83
13050 02-06 07:15:54.240 3140 3140 D keymaster_4_attestation_record_cpp: [006] 77 02 05 00 bf 85 3e 03 02 01 00 bf 85 40 2a 30
13051 02-06 07:15:54.240 3140 3140 D keymaster_4_attestation_record_cpp: [007] 28 04 20 c2 94 47 2a b9 ee f2 c2 bc 4c 85 33 a3
13052 02-06 07:15:54.240 3140 3140 D keymaster_4_attestation_record_cpp: [008] 20 d6 21 11 af d4 44 57 f0 af 96 0f eb a8 92 86
13053 02-06 07:15:54.240 3140 3140 D keymaster_4_attestation_record_cpp: [009] f3 9d e4 01 01 ff 0a 01 00 bf 85 41 05 02 03 01
13054 02-06 07:15:54.240 3140 3140 D keymaster_4_attestation_record_cpp: [00a] ad b0 bf 85 42 05 02 03 03 15 de
13055 02-06 07:15:54.240 3140 3140 D keymaster_4_attestation_record_cpp: ==dump asn1_key_desc end, size = 171
13056 02-06 07:15:54.260 3140 3140 E keymaster_4_attestation_record_cpp: d2i_KM_KEY_DESCRIPTION failed, return -1000
13057 02-06 07:15:54.261 3140 3140 E keymaster_hidl_hal_test: parse_attestation_record failed error: -1000

相关代码:

ErrorCode parse_attestation_record(const uint8_t* asn1_key_desc, size_t asn1_key_desc_len,
                                   uint32_t* attestation_version,  //
                                   SecurityLevel* attestation_security_level,
                                   uint32_t* keymaster_version,
                                   SecurityLevel* keymaster_security_level,
                                   hidl_vec<uint8_t>* attestation_challenge,
                                   AuthorizationSet* software_enforced,
                                   AuthorizationSet* tee_enforced,  //
                                   hidl_vec<uint8_t>* unique_id) {
    ALOGD("parse_attestation_record enter");
    ALOGD("==dump asn1_key_desc start, size = %zu", asn1_key_desc_len);
    atts_dump((uint8_t*)asn1_key_desc, (uint32_t)asn1_key_desc_len);
    ALOGD("==dump asn1_key_desc end, size = %zu", asn1_key_desc_len);
    const uint8_t* p = asn1_key_desc;
    KM_KEY_DESCRIPTION_Ptr record(d2i_KM_KEY_DESCRIPTION(nullptr, &p, asn1_key_desc_len));
    if (!record.get()) {
        ALOGE("d2i_KM_KEY_DESCRIPTION failed, return -1000");
        return ErrorCode::UNKNOWN_ERROR;
    }

    //省略若干

    return extract_auth_list(record->tee_enforced, tee_enforced);
}

从log中可以看到,我们已经打印出asn1_key_desc的值,将该值在http://lapo.it/asn1js/ 中进行ASN.1的解析,同时在boringssl中增加log打印(printf打印,编译出来的VTS程序在执行时,相关打印会在console中输出)。

结合IKeymasterDevice.hal中KeyDescription的定义,再将以上解析和log进行对比,能看出key description的异常在RootOfTrust中:

数据:

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 3d 05 02 03 10 5e 37 bf 85 45 05 04 03 66 6f 6f 30 79 a1 08 31 06 02 01 02 02 01 03 a2 03 02 01 01 a3 04 02 02 08 00 a5 05 31 03 02 01 04 a6 05 31 03 02 01 05 bf 81 48 05 02 03 01 00 01 bf 83 77 02 05 00 bf 85 3e 03 02 01 00 bf 85 40 2a 30 28 04 20 c9 a1 7d 3a a3 7b 40 ba 46 ba 86 31 f9 3b 8d 87 ce 05 4c f7 74 91 1b b0 ca 3c bd 77 ae da 27 fc 01 01 ff 0a 01 00 bf 85 41 05 02 03 01 ad b0 bf 85 42 05 02 03 03 15 de  

解析异常点:

    [704] (1 elem)
      SEQUENCE (3 elem)
        OCTET STRING (32 byte) C9A17D3AA37B40BA46BA8631F93B8D87CE054CF774911BB0CA3CBD77AEDA27FC 
        BOOLEAN true 
        ENUMERATED 0
IKeymasterDevice.hal中704定义:
     *     rootOfTrust                [704] EXPLICIT RootOfTrust OPTIONAL,

* RootOfTrust ::= SEQUENCE {
* verifiedBootKey OCTET_STRING,
* deviceLocked BOOLEAN,
* verifiedBootState VerifiedBootState,
* # verifiedBootHash must contain 32-byte value that represents the state of all binaries
* # or other components validated by verified boot. Updating any verified binary or
* # component must cause this value to change.
* verifiedBootHash OCTET_STRING,
* }

可见ROT中存在4个分量,但实际解析出来的只有3个,缺了一个OCTET_STRING。

封装ROT信息部分在TA中实现如下:

/**
 * \brief           Writes RootOfTrust to a buffer
 *
 * \note            This function works backwards in data buffer.
 *
 * \param p         Pointer to the array to be populated. If no memory allocated
 *		    - allocation will be processed inside this routine.
 * \param len	    Length of resulting array.
 *
 * \return          0 on success, -1 on failure.
 */
static int asn1_write_rot (uint8_t verified_boot, unsigned char **p,
                           size_t *len) {
	int len_ret = 0, ret;
	unsigned char buf[ASN1_BUF_LEN_DEFAULT];
	unsigned char *ptr = buf + sizeof(buf);
	unsigned char *start = buf;
	TEE_Result res = TEE_SUCCESS;

	//get root of device data from libhandlerot library
	root_of_trust_info_t device_rot;
	memset(&device_rot, 0, sizeof(root_of_trust_info_t));

	res = get_device_rot(&device_rot);
	DMSG("get_device_rot result:%d \n", res);

	int lock_state = device_rot.devcelock_state;

	MBEDTLS_ASN1_CHK_ADD(len_ret, mbedtls_asn1_write_enum(&ptr, start,
	                                                      verified_boot));
	MBEDTLS_ASN1_CHK_ADD(len_ret, mbedtls_asn1_write_bool(&ptr, start,
	                                                      lock_state));
	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_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;
}

从代码看,确实只封装了3个分量,分别是verified boot状态,lock state状态和digest数组。

根据IKeymasterDevice.hal中的定义,调整ROT的封装,先封装digest数组,接着是verified boot状态,lock状态,最后是key数组。

修改后的TA更新之后,测试结果如下

hardware/interfaces/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp:454: Failure

Value of: device_locked
Actual: true
Expected: false
hardware/interfaces/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp:465: Failure
Value of: device_locked
Actual: true
Expected: false
hardware/interfaces/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp:483: Failure
Expected equality of these values:
verified_boot_state
Which is: 0
KM_VERIFIED_BOOT_UNVERIFIED
Which is: 2
hardware/interfaces/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp:485: Failure
Expected equality of these values:
0
memcmp(verified_boot_key.data(), empty_boot_key.data(), verified_boot_key.size())
Which is: 1
[ FAILED ] PerInstance/AttestationTest.RsaAttestation/0_default, where GetParam() = "default" (18936 ms)
[----------] 1 test from PerInstance/AttestationTest (18936 ms total)

[----------] Global test environment tear-down
[==========] 1 test from 1 test suite ran. (18937 ms total)
[ PASSED ] 0 tests.
[ FAILED ] 1 test, listed below:
[ FAILED ] PerInstance/AttestationTest.RsaAttestation/0_default, where GetParam() = "default"

1 FAILED TEST

异常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);
        }

        if (!property_get_bool("ro.debuggable", false)) {
            EXPECT_TRUE(device_locked);
        } else {
            EXPECT_FALSE(device_locked);
        }

    EXPECT_NE(property_get("ro.boot.verifiedbootstate", property_value, ""), 0);
    if (!strcmp(property_value, "green")) {
        EXPECT_EQ(verified_boot_state, KM_VERIFIED_BOOT_VERIFIED);
        EXPECT_NE(0, memcmp(verified_boot_key.data(), empty_boot_key.data(),
                            verified_boot_key.size()));
    } else if (!strcmp(property_value, "yellow")) {
        EXPECT_EQ(verified_boot_state, KM_VERIFIED_BOOT_SELF_SIGNED);
        EXPECT_NE(0, memcmp(verified_boot_key.data(), empty_boot_key.data(),
                            verified_boot_key.size()));
    } else 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()));
    } else if (!strcmp(property_value, "red")) {
        EXPECT_EQ(verified_boot_state, KM_VERIFIED_BOOT_FAILED);
    } else {
        EXPECT_EQ(verified_boot_state, KM_VERIFIED_BOOT_UNVERIFIED);
        EXPECT_NE(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中增加的log打印如下:

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

TA中log说明lock值为1,封装到ROT中的verified boot值为0。这个与系统属性匹配不上,系统属性显示设备状态为unlocked,verified boot state为orange。

也就是说TA中封装错误了。

核查后,修改TA中封装的逻辑,更新TA后测试仍旧有异常。

异常3:

hardware/interfaces/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp:485: Failure
Expected equality of these values:
0
memcmp(verified_boot_key.data(), empty_boot_key.data(), verified_boot_key.size())
Which is: 1
[ FAILED ] PerInstance/AttestationTest.RsaAttestation/0_default, where GetParam() = "default" (18823 ms)
[----------] 1 test from PerInstance/AttestationTest (18823 ms total)

[----------] Global test environment tear-down
[==========] 1 test from 1 test suite ran. (18824 ms total)
[ PASSED ] 0 tests.
[ FAILED ] 1 test, listed below:
[ FAILED ] PerInstance/AttestationTest.RsaAttestation/0_default, where GetParam() = "default"

1 FAILED TEST

对应VTS代码:


else 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())); }

其中std::string empty_boot_key(32, '\0');

也就是说,当verified boot状态为orange时,预期verified boot key需要封装一个空串进来。

根据该判定逻辑,修改TA中对应封装代码。

更新TA后,出现如下测试异常。

异常4:

hardware/interfaces/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp:370: Failure
Expected: (att_attestation_version) >= (3U), actual: 2 vs 3
hardware/interfaces/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp:374: Failure
Expected: (att_keymaster_version) >= (4U), actual: 3 vs 4

这两行异常对应VTS代码为:

    EXPECT_GE(att_attestation_version, 3U);

    expected_sw_enforced.push_back(TAG_ATTESTATION_APPLICATION_ID, HidlBuf(app_id));

    EXPECT_GE(att_keymaster_version, 4U);

IKeymasterDevice.hal中定义:

* KeyDescription ::= SEQUENCE {
* attestationVersion INTEGER, # Value 3
* attestationSecurityLevel SecurityLevel, # See below
* keymasterVersion INTEGER, # Value 4
* keymasterSecurityLevel SecurityLevel, # See below
* attestationChallenge OCTET_STRING, # Tag::ATTESTATION_CHALLENGE from attestParams
* uniqueId OCTET_STRING, # Empty unless key has Tag::INCLUDE_UNIQUE_ID
* softwareEnforced AuthorizationList, # See below
* hardwareEnforced AuthorizationList, # See below
* }

TA中定义:

keymaster\ta\mbedtls_proxy.c

#define KEYMASTER_VERSION 3
#define ATTESTATION_VERSION 2

修改TA中定义后,测试PASS.

[ OK ] PerInstance/AttestationTest.RsaAttestation/0_default (16978 ms)
[----------] 1 test from PerInstance/AttestationTest (16978 ms total)

[----------] Global test environment tear-down
[==========] 1 test from 1 test suite ran. (16979 ms total)
[ PASSED ] 1 test.

总结:

耗时最久的是异常1的分析,因为boringssl中的log输出,还要分析数据具体的解析,其次获取设备rot信息,因为这部分代码是另外一个同事写的,smc调用最终在BL31中实现的,还跑去看了这部分的代码,才发现底层的实现和android这边的定义有差异。所以设备状态才反了。

 

posted @ 2023-02-08 14:41  xiululu  阅读(66)  评论(0编辑  收藏  举报