接口定义:
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