首页 > 其他分享 >km4.0:getHmacSharingParameters

km4.0:getHmacSharingParameters

时间:2023-02-10 10:47:10浏览次数:37  
标签:nonce const HmacSharingParameters uint8 km4.0 seed params getHmacSharingParamete

接口定义:

hardware/interfaces/keymaster/4.0/IKeymasterDevice.hal

看返回值,最终目的是生成一个HmacSharingParameters对象

/**
 * Start the creation of an HMAC key, shared with another IKeymasterDevice implementation.  Any
 * device with a StrongBox IKeymasterDevice has two IKeymasterDevice instances, because there
 * must be a TEE Keymaster as well.  The HMAC key used to MAC and verify authentication tokens
 * (HardwareAuthToken, VerificationToken and ConfirmationToken all use this HMAC key) must be
 * shared between TEE and StrongBox so they can each validate tokens produced by the other.
 * This method is the first step in the process for agreeing on a shared key.  It is called by
 * Android during startup.  The system calls it on each of the HAL instances and collects the
 * results in preparation for the second step.
 *
 * @return error ErrorCode::OK on success, ErrorCode::UNIMPLEMENTED if HMAC agreement is not
 *         implemented (note that all 4.0::IKeymasterDevice HALS must implement HMAC agreement,
 *         regardless of whether or not the HAL will be used on a device with StrongBox), or
 *         ErrorCode::UNKNOWN_ERROR if the parameters cannot be returned.
 *
 * @return params The HmacSharingParameters to use.  As specified in the HmacSharingParameters
 *         documentation in types.hal, the seed must contain the same value in every invocation
 *         of the method on a given device, and the nonce must return the same value for every
 *         invocation during a boot session.
 */
getHmacSharingParameters() generates (ErrorCode error, HmacSharingParameters params);

关键数据类型:

system/keymaster/include/keymaster/android_keymaster_messages.h

struct HmacSharingParameters : public Serializable {
    HmacSharingParameters() : seed({}) { memset(nonce, 0, sizeof(nonce)); }
    HmacSharingParameters(HmacSharingParameters&& other) {
        seed = move(other.seed);
        memcpy(nonce, other.nonce, sizeof(nonce));
    }

    void SetSeed(KeymasterBlob&& value) { seed = move(value); }

    size_t SerializedSize() const override;
    uint8_t* Serialize(uint8_t* buf, const uint8_t* end) const override;
    bool Deserialize(const uint8_t** buf_ptr, const uint8_t* end) override;

    KeymasterBlob seed{};
    uint8_t nonce[32];
};

从HmacSharingParameters定义来看,该对象需要包含一个seed和一个随机数,以供后续使用。

struct GetHmacSharingParametersResponse : public KeymasterResponse {
    explicit GetHmacSharingParametersResponse(int32_t ver = MAX_MESSAGE_VERSION)
        : KeymasterResponse(ver) {}
    GetHmacSharingParametersResponse(GetHmacSharingParametersResponse&& other)
        : KeymasterResponse(other.message_version), params(move(other.params)) {}

    void SetSeed(KeymasterBlob&& seed_data) { params.SetSeed(move(seed_data)); }

    size_t NonErrorSerializedSize() const override { return params.SerializedSize(); }
    uint8_t* NonErrorSerialize(uint8_t* buf, const uint8_t* end) const override {
        return params.Serialize(buf, end);
    }
    bool NonErrorDeserialize(const uint8_t** buf_ptr, const uint8_t* end) override {
        return params.Deserialize(buf_ptr, end);
    }

    HmacSharingParameters params;
};
bool HmacSharingParameters::Deserialize(const uint8_t** buf_ptr, const uint8_t* end) {
    return deserialize_blob(&seed, buf_ptr, end) &&
           copy_from_buf(buf_ptr, end, nonce, sizeof(nonce));
}
static bool deserialize_blob(keymaster_blob_t* blob, const uint8_t** buf_ptr, const uint8_t* end) {
    delete[] blob->data;
    *blob = {};
    UniquePtr<uint8_t[]> deserialized_blob;
    if (!copy_size_and_data_from_buf(buf_ptr, end, &blob->data_length, &deserialized_blob))
        return false;
    blob->data = deserialized_blob.release();
    return true;
}

TA中实现,返回值的封装要参考GetHmacSharingParametersResponse的Deserialize部分,这样解析才不会出错。

软实现参考代码:

system/keymaster/km_openssl/soft_keymaster_enforcement.cpp

keymaster_error_t
SoftKeymasterEnforcement::GetHmacSharingParameters(HmacSharingParameters* params) {
    if (!have_saved_params_) {
        saved_params_.seed = {};//seed为空串
        RAND_bytes(saved_params_.nonce, 32);//生成随机数
        have_saved_params_ = true;
    }
    params->seed = saved_params_.seed;
    memcpy(params->nonce, saved_params_.nonce, sizeof(params->nonce));
    return KM_ERROR_OK;
}

keymaster TA中实现:

TA中实现完全参考软实现,需要注意的部分是返回值封装,对照HmacSharingParameters::Deserialize的实现逐个来就行。

static keymaster_error_t TA_getHmacSharingParameters(TEE_Param params[TEE_NUM_PARAMS])
{
	uint8_t *out = NULL;
	keymaster_error_t res = KM_ERROR_OK;

	out = (uint8_t *) params[1].memref.buffer;

	if (!s_nonce_generated) {
		TEE_GenerateRandom(s_nonce, HMAC_NONCE_SIZE);
		TEE_MemFill(&s_seed, 0, sizeof(s_seed));
		s_nonce_generated = true;
	}

        //输出部分逐个封装,先封装返回值,成功或失败,再封装seed(先长度再值),最后是nonce
	out += TA_serialize_rsp_err(out, &res);

	uint32_t seed_size = 0;
	TEE_MemMove(out, &seed_size, sizeof(seed_size));
	out += sizeof(seed_size);

	TEE_MemMove(out, s_nonce, HMAC_NONCE_SIZE);
	out += HMAC_NONCE_SIZE;

	params[1].memref.size = out - (uint8_t *)params[1].memref.buffer;

	return res;
}

VTS测试结果:

相关VTS用例的测试,至少能保证在接口实现上不会有大问题。

# ./VtsHalKeymasterV4_0TargetTest --gtest_filter=PerInstance/HmacKeySharingTest.GetParameters/0_default
Note: Google Test filter = PerInstance/HmacKeySharingTest.GetParameters/0_default
[==========] Running 1 test from 1 test suite.
[----------] Global test environment set-up.
[----------] 1 test from PerInstance/HmacKeySharingTest
[ RUN      ] PerInstance/HmacKeySharingTest.GetParameters/0_default
[       OK ] PerInstance/HmacKeySharingTest.GetParameters/0_default (205 ms)
[----------] 1 test from PerInstance/HmacKeySharingTest (205 ms total)

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

 

标签:nonce,const,HmacSharingParameters,uint8,km4.0,seed,params,getHmacSharingParamete
From: https://www.cnblogs.com/xiululu/p/17108088.html

相关文章

  • km4.0: getHardwareInfo
    直接在CA侧实现的接口。接口说明:hardware/interfaces/keymaster/4.0/IKeymasterDevice.hal201/**202*ReturnsinformationabouttheunderlyingIKeymas......