1094332d3Sopenharmony_ci/*
2094332d3Sopenharmony_ci * Copyright (C) 2023-2024 Huawei Device Co., Ltd.
3094332d3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4094332d3Sopenharmony_ci * you may not use this file except in compliance with the License.
5094332d3Sopenharmony_ci * You may obtain a copy of the License at
6094332d3Sopenharmony_ci *
7094332d3Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8094332d3Sopenharmony_ci *
9094332d3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10094332d3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11094332d3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12094332d3Sopenharmony_ci * See the License for the specific language governing permissions and
13094332d3Sopenharmony_ci * limitations under the License.
14094332d3Sopenharmony_ci */
15094332d3Sopenharmony_ci
16094332d3Sopenharmony_ci#include "attribute.h"
17094332d3Sopenharmony_ci
18094332d3Sopenharmony_ci#include "securec.h"
19094332d3Sopenharmony_ci
20094332d3Sopenharmony_ci#include "adaptor_log.h"
21094332d3Sopenharmony_ci#include "adaptor_memory.h"
22094332d3Sopenharmony_ci
23094332d3Sopenharmony_ci#ifdef IAM_TEST_ENABLE
24094332d3Sopenharmony_ci#define IAM_STATIC
25094332d3Sopenharmony_ci#else
26094332d3Sopenharmony_ci#define IAM_STATIC static
27094332d3Sopenharmony_ci#endif
28094332d3Sopenharmony_ci
29094332d3Sopenharmony_ciAttributeKey g_attributeKeyArray[] = {
30094332d3Sopenharmony_ci    ATTR_RESULT_CODE,
31094332d3Sopenharmony_ci    ATTR_SIGNATURE,
32094332d3Sopenharmony_ci    ATTR_TEMPLATE_ID,
33094332d3Sopenharmony_ci    ATTR_REMAIN_ATTEMPTS,
34094332d3Sopenharmony_ci    ATTR_LOCKOUT_DURATION,
35094332d3Sopenharmony_ci    ATTR_SCHEDULE_ID,
36094332d3Sopenharmony_ci    ATTR_DATA,
37094332d3Sopenharmony_ci    ATTR_PIN_SUB_TYPE,
38094332d3Sopenharmony_ci    ATTR_ACL,
39094332d3Sopenharmony_ci    ATTR_TIME_STAMP,
40094332d3Sopenharmony_ci    ATTR_ROOT_SECRET,
41094332d3Sopenharmony_ci    ATTR_ROOT,
42094332d3Sopenharmony_ci    ATTR_LOCAL_UDID,
43094332d3Sopenharmony_ci    ATTR_PEER_UDID,
44094332d3Sopenharmony_ci    ATTR_PUBLIC_KEY,
45094332d3Sopenharmony_ci    ATTR_CHALLENGE,
46094332d3Sopenharmony_ci    PIN_ATTR_MSG_ID,
47094332d3Sopenharmony_ci    PIN_ATTR_ALGO_VERSION,
48094332d3Sopenharmony_ci    PIN_ATTR_ALGO_PARAM,
49094332d3Sopenharmony_ci    PIN_ATTR_KEK_SALT,
50094332d3Sopenharmony_ci    PIN_ATTR_KEK_IV,
51094332d3Sopenharmony_ci    PIN_ATTR_KEK_SECRET,
52094332d3Sopenharmony_ci    PIN_ATTR_KEK_TAG,
53094332d3Sopenharmony_ci};
54094332d3Sopenharmony_ci
55094332d3Sopenharmony_ci#define ARRAY_LENGTH(array) (uint32_t)(sizeof(array) / sizeof((array)[0]))
56094332d3Sopenharmony_ci#define ATTRIBUTE_LEN (ARRAY_LENGTH(g_attributeKeyArray))
57094332d3Sopenharmony_ci
58094332d3Sopenharmony_citypedef struct {
59094332d3Sopenharmony_ci    Uint8Array *values[ATTRIBUTE_LEN];
60094332d3Sopenharmony_ci} AttributeImpl;
61094332d3Sopenharmony_ci
62094332d3Sopenharmony_ciIAM_STATIC uint32_t Ntohl32(uint32_t in)
63094332d3Sopenharmony_ci{
64094332d3Sopenharmony_ci    return in;
65094332d3Sopenharmony_ci}
66094332d3Sopenharmony_ci
67094332d3Sopenharmony_ciIAM_STATIC uint32_t Htonl32(uint32_t in)
68094332d3Sopenharmony_ci{
69094332d3Sopenharmony_ci    return in;
70094332d3Sopenharmony_ci}
71094332d3Sopenharmony_ci
72094332d3Sopenharmony_ciIAM_STATIC uint64_t Ntohl64(uint64_t in)
73094332d3Sopenharmony_ci{
74094332d3Sopenharmony_ci    return in;
75094332d3Sopenharmony_ci}
76094332d3Sopenharmony_ci
77094332d3Sopenharmony_ciIAM_STATIC uint64_t Htonl64(uint64_t in)
78094332d3Sopenharmony_ci{
79094332d3Sopenharmony_ci    return in;
80094332d3Sopenharmony_ci}
81094332d3Sopenharmony_ci
82094332d3Sopenharmony_ciIAM_STATIC void Ntohl64Array(Uint64Array *array)
83094332d3Sopenharmony_ci{
84094332d3Sopenharmony_ci    for (uint32_t i = 0; i < array->len; i++) {
85094332d3Sopenharmony_ci        array->data[i] = Ntohl64(array->data[i]);
86094332d3Sopenharmony_ci    }
87094332d3Sopenharmony_ci}
88094332d3Sopenharmony_ci
89094332d3Sopenharmony_ciIAM_STATIC void Htonl64Array(Uint64Array *array)
90094332d3Sopenharmony_ci{
91094332d3Sopenharmony_ci    for (uint32_t i = 0; i < array->len; i++) {
92094332d3Sopenharmony_ci        array->data[i] = Htonl64(array->data[i]);
93094332d3Sopenharmony_ci    }
94094332d3Sopenharmony_ci}
95094332d3Sopenharmony_ci
96094332d3Sopenharmony_ciIAM_STATIC ResultCode GetAttributeIndex(AttributeKey key, uint32_t *index)
97094332d3Sopenharmony_ci{
98094332d3Sopenharmony_ci    for (uint32_t i = 0; i < ATTRIBUTE_LEN; ++i) {
99094332d3Sopenharmony_ci        if (g_attributeKeyArray[i] == key) {
100094332d3Sopenharmony_ci            *index = i;
101094332d3Sopenharmony_ci            return RESULT_SUCCESS;
102094332d3Sopenharmony_ci        }
103094332d3Sopenharmony_ci    }
104094332d3Sopenharmony_ci
105094332d3Sopenharmony_ci    return RESULT_GENERAL_ERROR;
106094332d3Sopenharmony_ci}
107094332d3Sopenharmony_ci
108094332d3Sopenharmony_ciIAM_STATIC ResultCode ReadDataFromMsg(const Uint8Array msg, uint32_t *readIndex, Uint8Array *retData)
109094332d3Sopenharmony_ci{
110094332d3Sopenharmony_ci    if (msg.len <= *readIndex) {
111094332d3Sopenharmony_ci        LOG_ERROR("msg length is not enough");
112094332d3Sopenharmony_ci        return RESULT_GENERAL_ERROR;
113094332d3Sopenharmony_ci    }
114094332d3Sopenharmony_ci
115094332d3Sopenharmony_ci    if (msg.len - *readIndex < retData->len) {
116094332d3Sopenharmony_ci        LOG_ERROR("remain data length is not enough");
117094332d3Sopenharmony_ci        return RESULT_GENERAL_ERROR;
118094332d3Sopenharmony_ci    }
119094332d3Sopenharmony_ci
120094332d3Sopenharmony_ci    if (memcpy_s(retData->data, retData->len, msg.data + *readIndex, retData->len) != EOK) {
121094332d3Sopenharmony_ci        LOG_ERROR("memcpy_s fail");
122094332d3Sopenharmony_ci        return RESULT_GENERAL_ERROR;
123094332d3Sopenharmony_ci    }
124094332d3Sopenharmony_ci
125094332d3Sopenharmony_ci    *readIndex += retData->len;
126094332d3Sopenharmony_ci    return RESULT_SUCCESS;
127094332d3Sopenharmony_ci}
128094332d3Sopenharmony_ci
129094332d3Sopenharmony_ciIAM_STATIC ResultCode ReadUint32FromMsg(const Uint8Array msg, uint32_t *readIndex, uint32_t *retValue)
130094332d3Sopenharmony_ci{
131094332d3Sopenharmony_ci    uint32_t netOrderValue;
132094332d3Sopenharmony_ci    Uint8Array uint8Data = { (uint8_t *)&netOrderValue, sizeof(netOrderValue) };
133094332d3Sopenharmony_ci    ResultCode result = ReadDataFromMsg(msg, readIndex, &uint8Data);
134094332d3Sopenharmony_ci    if (result != RESULT_SUCCESS) {
135094332d3Sopenharmony_ci        LOG_ERROR("read data fail");
136094332d3Sopenharmony_ci        return RESULT_GENERAL_ERROR;
137094332d3Sopenharmony_ci    }
138094332d3Sopenharmony_ci
139094332d3Sopenharmony_ci    *retValue = Ntohl32(netOrderValue);
140094332d3Sopenharmony_ci    return RESULT_SUCCESS;
141094332d3Sopenharmony_ci}
142094332d3Sopenharmony_ci
143094332d3Sopenharmony_ciIAM_STATIC ResultCode WriteDataToMsg(Uint8Array *msg, uint32_t *writeIndex, const Uint8Array data)
144094332d3Sopenharmony_ci{
145094332d3Sopenharmony_ci    if (msg->len <= *writeIndex) {
146094332d3Sopenharmony_ci        LOG_ERROR("msg length is not enough");
147094332d3Sopenharmony_ci        return RESULT_GENERAL_ERROR;
148094332d3Sopenharmony_ci    }
149094332d3Sopenharmony_ci
150094332d3Sopenharmony_ci    if (msg->len - *writeIndex < data.len) {
151094332d3Sopenharmony_ci        LOG_ERROR("remain data size is not enough");
152094332d3Sopenharmony_ci        return RESULT_GENERAL_ERROR;
153094332d3Sopenharmony_ci    }
154094332d3Sopenharmony_ci
155094332d3Sopenharmony_ci    if (memcpy_s(msg->data + *writeIndex, msg->len - *writeIndex, data.data, data.len) != EOK) {
156094332d3Sopenharmony_ci        LOG_ERROR("memcpy_s fail");
157094332d3Sopenharmony_ci        return RESULT_GENERAL_ERROR;
158094332d3Sopenharmony_ci    }
159094332d3Sopenharmony_ci
160094332d3Sopenharmony_ci    *writeIndex += data.len;
161094332d3Sopenharmony_ci    return RESULT_SUCCESS;
162094332d3Sopenharmony_ci}
163094332d3Sopenharmony_ci
164094332d3Sopenharmony_ciIAM_STATIC ResultCode WriteUInt32ToMsg(Uint8Array *msg, uint32_t *writeIndex, uint32_t value)
165094332d3Sopenharmony_ci{
166094332d3Sopenharmony_ci    uint32_t netOrderValue = Htonl32(value);
167094332d3Sopenharmony_ci    ResultCode result =
168094332d3Sopenharmony_ci        WriteDataToMsg(msg, writeIndex, (Uint8Array){ (uint8_t *)&netOrderValue, sizeof(netOrderValue) });
169094332d3Sopenharmony_ci    if (result != RESULT_SUCCESS) {
170094332d3Sopenharmony_ci        LOG_ERROR("write data fail");
171094332d3Sopenharmony_ci        return RESULT_GENERAL_ERROR;
172094332d3Sopenharmony_ci    }
173094332d3Sopenharmony_ci    return RESULT_SUCCESS;
174094332d3Sopenharmony_ci}
175094332d3Sopenharmony_ci
176094332d3Sopenharmony_ciIAM_STATIC ResultCode CheckAddReadIndex(const Uint8Array msg, uint32_t *readIndex, uint32_t length)
177094332d3Sopenharmony_ci{
178094332d3Sopenharmony_ci    if (msg.len <= (*readIndex)) {
179094332d3Sopenharmony_ci        LOG_ERROR("msg length is not enough");
180094332d3Sopenharmony_ci        return RESULT_GENERAL_ERROR;
181094332d3Sopenharmony_ci    }
182094332d3Sopenharmony_ci
183094332d3Sopenharmony_ci    if ((msg.len - (*readIndex)) < length) {
184094332d3Sopenharmony_ci        LOG_ERROR("remain data length is not enough");
185094332d3Sopenharmony_ci        return RESULT_GENERAL_ERROR;
186094332d3Sopenharmony_ci    }
187094332d3Sopenharmony_ci
188094332d3Sopenharmony_ci    (*readIndex) += length;
189094332d3Sopenharmony_ci    return RESULT_SUCCESS;
190094332d3Sopenharmony_ci}
191094332d3Sopenharmony_ci
192094332d3Sopenharmony_ciIAM_STATIC ResultCode ParseAttributeSerializedMsgInner(Attribute *attribute, const Uint8Array msg,
193094332d3Sopenharmony_ci    const Uint8Array *readBuffer)
194094332d3Sopenharmony_ci{
195094332d3Sopenharmony_ci    uint32_t readIndex = 0;
196094332d3Sopenharmony_ci    while (readIndex < msg.len) {
197094332d3Sopenharmony_ci        uint32_t type;
198094332d3Sopenharmony_ci        ResultCode readTypeResult = ReadUint32FromMsg(msg, &readIndex, &type);
199094332d3Sopenharmony_ci        IF_TRUE_LOGE_AND_RETURN_VAL(readTypeResult != RESULT_SUCCESS, RESULT_GENERAL_ERROR);
200094332d3Sopenharmony_ci
201094332d3Sopenharmony_ci        uint32_t length;
202094332d3Sopenharmony_ci        ResultCode readLengthResult = ReadUint32FromMsg(msg, &readIndex, &length);
203094332d3Sopenharmony_ci        IF_TRUE_LOGE_AND_RETURN_VAL(readLengthResult != RESULT_SUCCESS, RESULT_GENERAL_ERROR);
204094332d3Sopenharmony_ci
205094332d3Sopenharmony_ci        if (length > readBuffer->len) {
206094332d3Sopenharmony_ci            LOG_INFO("attribute:%{public}u too long:%{public}u, skip", type, length);
207094332d3Sopenharmony_ci            ResultCode checkAddReadIndexResult = CheckAddReadIndex(msg, &readIndex, length);
208094332d3Sopenharmony_ci            IF_TRUE_LOGE_AND_RETURN_VAL(checkAddReadIndexResult != RESULT_SUCCESS, RESULT_GENERAL_ERROR);
209094332d3Sopenharmony_ci            continue;
210094332d3Sopenharmony_ci        }
211094332d3Sopenharmony_ci
212094332d3Sopenharmony_ci        Uint8Array readData = { readBuffer->data, length };
213094332d3Sopenharmony_ci        if (length > 0) {
214094332d3Sopenharmony_ci            ResultCode readDataResult = ReadDataFromMsg(msg, &readIndex, &readData);
215094332d3Sopenharmony_ci            IF_TRUE_LOGE_AND_RETURN_VAL(readDataResult != RESULT_SUCCESS, RESULT_GENERAL_ERROR);
216094332d3Sopenharmony_ci        }
217094332d3Sopenharmony_ci
218094332d3Sopenharmony_ci        uint32_t attributeIndex;
219094332d3Sopenharmony_ci        if (GetAttributeIndex(type, &attributeIndex) != RESULT_SUCCESS) {
220094332d3Sopenharmony_ci            LOG_INFO("attribute:%{public}u not found, skip", type);
221094332d3Sopenharmony_ci            continue;
222094332d3Sopenharmony_ci        }
223094332d3Sopenharmony_ci
224094332d3Sopenharmony_ci        ResultCode setAttrResult = SetAttributeUint8Array(attribute, type, readData);
225094332d3Sopenharmony_ci        IF_TRUE_LOGE_AND_RETURN_VAL(setAttrResult != RESULT_SUCCESS, RESULT_GENERAL_ERROR);
226094332d3Sopenharmony_ci    }
227094332d3Sopenharmony_ci
228094332d3Sopenharmony_ci    return RESULT_SUCCESS;
229094332d3Sopenharmony_ci}
230094332d3Sopenharmony_ci
231094332d3Sopenharmony_ciIAM_STATIC ResultCode ParseAttributeSerializedMsg(Attribute *attribute, const Uint8Array msg)
232094332d3Sopenharmony_ci{
233094332d3Sopenharmony_ci    Uint8Array *readBuffer = CreateUint8ArrayBySize(MAX_EXECUTOR_MSG_LEN);
234094332d3Sopenharmony_ci    IF_TRUE_LOGE_AND_RETURN_VAL(readBuffer == NULL, RESULT_GENERAL_ERROR);
235094332d3Sopenharmony_ci
236094332d3Sopenharmony_ci    ResultCode result = ParseAttributeSerializedMsgInner(attribute, msg, readBuffer);
237094332d3Sopenharmony_ci    if (result != RESULT_SUCCESS) {
238094332d3Sopenharmony_ci        LOG_ERROR("ParseAttributeSerializedMsgInner fail");
239094332d3Sopenharmony_ci    }
240094332d3Sopenharmony_ci    DestroyUint8Array(&readBuffer);
241094332d3Sopenharmony_ci
242094332d3Sopenharmony_ci    return result;
243094332d3Sopenharmony_ci}
244094332d3Sopenharmony_ci
245094332d3Sopenharmony_ciAttribute *CreateEmptyAttribute(void)
246094332d3Sopenharmony_ci{
247094332d3Sopenharmony_ci    AttributeImpl *attribute = Malloc(sizeof(AttributeImpl));
248094332d3Sopenharmony_ci    IF_TRUE_LOGE_AND_RETURN_VAL(attribute == NULL, NULL);
249094332d3Sopenharmony_ci    (void)memset_s(attribute, sizeof(AttributeImpl), 0, sizeof(AttributeImpl));
250094332d3Sopenharmony_ci
251094332d3Sopenharmony_ci    return attribute;
252094332d3Sopenharmony_ci}
253094332d3Sopenharmony_ci
254094332d3Sopenharmony_ciAttribute *CreateAttributeFromSerializedMsg(const Uint8Array msg)
255094332d3Sopenharmony_ci{
256094332d3Sopenharmony_ci    IF_TRUE_LOGE_AND_RETURN_VAL(IS_ARRAY_NULL(msg), NULL);
257094332d3Sopenharmony_ci
258094332d3Sopenharmony_ci    Attribute *attribute = CreateEmptyAttribute();
259094332d3Sopenharmony_ci    if (attribute == NULL) {
260094332d3Sopenharmony_ci        LOG_ERROR("CreateEmptyAttribute failed");
261094332d3Sopenharmony_ci        return NULL;
262094332d3Sopenharmony_ci    }
263094332d3Sopenharmony_ci
264094332d3Sopenharmony_ci    ResultCode result = ParseAttributeSerializedMsg(attribute, msg);
265094332d3Sopenharmony_ci    if (result != RESULT_SUCCESS) {
266094332d3Sopenharmony_ci        LOG_ERROR("ParseAttributeSerializedMsg failed");
267094332d3Sopenharmony_ci        FreeAttribute((Attribute **)&attribute);
268094332d3Sopenharmony_ci        return NULL;
269094332d3Sopenharmony_ci    }
270094332d3Sopenharmony_ci
271094332d3Sopenharmony_ci    return attribute;
272094332d3Sopenharmony_ci}
273094332d3Sopenharmony_ci
274094332d3Sopenharmony_ciResultCode GetAttributeSerializedMsg(const Attribute *attributePublic, Uint8Array *retMsg)
275094332d3Sopenharmony_ci{
276094332d3Sopenharmony_ci    IF_TRUE_LOGE_AND_RETURN_VAL(attributePublic == NULL, RESULT_BAD_PARAM);
277094332d3Sopenharmony_ci    IF_TRUE_LOGE_AND_RETURN_VAL(retMsg == NULL, RESULT_BAD_PARAM);
278094332d3Sopenharmony_ci    IF_TRUE_LOGE_AND_RETURN_VAL(IS_ARRAY_NULL(*retMsg), RESULT_BAD_PARAM);
279094332d3Sopenharmony_ci
280094332d3Sopenharmony_ci    const AttributeImpl *attribute = (const AttributeImpl *)attributePublic;
281094332d3Sopenharmony_ci    uint32_t writeIndex = 0;
282094332d3Sopenharmony_ci    for (uint32_t i = 0; i < ATTRIBUTE_LEN; i++) {
283094332d3Sopenharmony_ci        Uint8Array *array = attribute->values[i];
284094332d3Sopenharmony_ci        if (array == NULL) {
285094332d3Sopenharmony_ci            continue;
286094332d3Sopenharmony_ci        }
287094332d3Sopenharmony_ci
288094332d3Sopenharmony_ci        ResultCode writeTypeResult = WriteUInt32ToMsg(retMsg, &writeIndex, g_attributeKeyArray[i]);
289094332d3Sopenharmony_ci        IF_TRUE_LOGE_AND_RETURN_VAL(writeTypeResult != RESULT_SUCCESS, RESULT_GENERAL_ERROR);
290094332d3Sopenharmony_ci
291094332d3Sopenharmony_ci        ResultCode writeLengthResult = WriteUInt32ToMsg(retMsg, &writeIndex, array->len);
292094332d3Sopenharmony_ci        IF_TRUE_LOGE_AND_RETURN_VAL(writeLengthResult != RESULT_SUCCESS, RESULT_GENERAL_ERROR);
293094332d3Sopenharmony_ci
294094332d3Sopenharmony_ci        if (array->len == 0) {
295094332d3Sopenharmony_ci            continue;
296094332d3Sopenharmony_ci        }
297094332d3Sopenharmony_ci        ResultCode writeDataResult =
298094332d3Sopenharmony_ci            WriteDataToMsg(retMsg, &writeIndex, *array);
299094332d3Sopenharmony_ci        IF_TRUE_LOGE_AND_RETURN_VAL(writeDataResult != RESULT_SUCCESS, RESULT_GENERAL_ERROR);
300094332d3Sopenharmony_ci    }
301094332d3Sopenharmony_ci
302094332d3Sopenharmony_ci    retMsg->len = writeIndex;
303094332d3Sopenharmony_ci    return RESULT_SUCCESS;
304094332d3Sopenharmony_ci}
305094332d3Sopenharmony_ci
306094332d3Sopenharmony_civoid FreeAttribute(Attribute **attribute)
307094332d3Sopenharmony_ci{
308094332d3Sopenharmony_ci    IF_TRUE_LOGE_AND_RETURN(attribute == NULL);
309094332d3Sopenharmony_ci    IF_TRUE_LOGE_AND_RETURN(*attribute == NULL);
310094332d3Sopenharmony_ci    AttributeImpl *impl = (AttributeImpl *)*attribute;
311094332d3Sopenharmony_ci    for (uint32_t i = 0; i < ATTRIBUTE_LEN; ++i) {
312094332d3Sopenharmony_ci        DestroyUint8Array(&impl->values[i]);
313094332d3Sopenharmony_ci    }
314094332d3Sopenharmony_ci
315094332d3Sopenharmony_ci    IAM_FREE_AND_SET_NULL(*attribute);
316094332d3Sopenharmony_ci}
317094332d3Sopenharmony_ci
318094332d3Sopenharmony_ciResultCode GetAttributeUint32(const Attribute *attribute, AttributeKey key, uint32_t *value)
319094332d3Sopenharmony_ci{
320094332d3Sopenharmony_ci    IF_TRUE_LOGE_AND_RETURN_VAL(attribute == NULL, RESULT_BAD_PARAM);
321094332d3Sopenharmony_ci    IF_TRUE_LOGE_AND_RETURN_VAL(value == NULL, RESULT_BAD_PARAM);
322094332d3Sopenharmony_ci
323094332d3Sopenharmony_ci    uint32_t netOrderValue;
324094332d3Sopenharmony_ci    Uint8Array uint32Data = { (uint8_t *)&netOrderValue, sizeof(netOrderValue) };
325094332d3Sopenharmony_ci    ResultCode getAttrResult = GetAttributeUint8Array(attribute, key, &uint32Data);
326094332d3Sopenharmony_ci    IF_TRUE_LOGE_AND_RETURN_VAL(getAttrResult != RESULT_SUCCESS, RESULT_GENERAL_ERROR);
327094332d3Sopenharmony_ci    IF_TRUE_LOGE_AND_RETURN_VAL(uint32Data.len != sizeof(netOrderValue), RESULT_GENERAL_ERROR);
328094332d3Sopenharmony_ci
329094332d3Sopenharmony_ci    *value = Ntohl32(netOrderValue);
330094332d3Sopenharmony_ci    return RESULT_SUCCESS;
331094332d3Sopenharmony_ci}
332094332d3Sopenharmony_ci
333094332d3Sopenharmony_ciResultCode SetAttributeUint32(Attribute *attribute, AttributeKey key, const uint32_t value)
334094332d3Sopenharmony_ci{
335094332d3Sopenharmony_ci    IF_TRUE_LOGE_AND_RETURN_VAL(attribute == NULL, RESULT_BAD_PARAM);
336094332d3Sopenharmony_ci
337094332d3Sopenharmony_ci    uint32_t netOrderValue = Htonl32(value);
338094332d3Sopenharmony_ci    ResultCode result =
339094332d3Sopenharmony_ci        SetAttributeUint8Array(attribute, key, (Uint8Array) { (uint8_t *)&netOrderValue, sizeof(netOrderValue) });
340094332d3Sopenharmony_ci    IF_TRUE_LOGE_AND_RETURN_VAL(result != RESULT_SUCCESS, RESULT_GENERAL_ERROR);
341094332d3Sopenharmony_ci
342094332d3Sopenharmony_ci    return result;
343094332d3Sopenharmony_ci}
344094332d3Sopenharmony_ci
345094332d3Sopenharmony_ciResultCode GetAttributeInt32(const Attribute *attribute, AttributeKey key, int32_t *retValue)
346094332d3Sopenharmony_ci{
347094332d3Sopenharmony_ci    IF_TRUE_LOGE_AND_RETURN_VAL(attribute == NULL, RESULT_BAD_PARAM);
348094332d3Sopenharmony_ci    IF_TRUE_LOGE_AND_RETURN_VAL(retValue == NULL, RESULT_BAD_PARAM);
349094332d3Sopenharmony_ci
350094332d3Sopenharmony_ci    return GetAttributeUint32(attribute, key, (uint32_t *)retValue);
351094332d3Sopenharmony_ci}
352094332d3Sopenharmony_ci
353094332d3Sopenharmony_ciResultCode SetAttributeInt32(Attribute *attribute, AttributeKey key, const int32_t value)
354094332d3Sopenharmony_ci{
355094332d3Sopenharmony_ci    IF_TRUE_LOGE_AND_RETURN_VAL(attribute == NULL, RESULT_BAD_PARAM);
356094332d3Sopenharmony_ci
357094332d3Sopenharmony_ci    return SetAttributeUint32(attribute, key, (uint32_t)value);
358094332d3Sopenharmony_ci}
359094332d3Sopenharmony_ci
360094332d3Sopenharmony_ciResultCode GetAttributeUint64(const Attribute *attribute, AttributeKey key, uint64_t *retValue)
361094332d3Sopenharmony_ci{
362094332d3Sopenharmony_ci    IF_TRUE_LOGE_AND_RETURN_VAL(attribute == NULL, RESULT_BAD_PARAM);
363094332d3Sopenharmony_ci    IF_TRUE_LOGE_AND_RETURN_VAL(retValue == NULL, RESULT_BAD_PARAM);
364094332d3Sopenharmony_ci
365094332d3Sopenharmony_ci    uint64_t netOrderValue;
366094332d3Sopenharmony_ci    Uint8Array uint64Data = { (uint8_t *)&netOrderValue, sizeof(netOrderValue) };
367094332d3Sopenharmony_ci    ResultCode getAttrResult = GetAttributeUint8Array(attribute, key, &uint64Data);
368094332d3Sopenharmony_ci    IF_TRUE_LOGE_AND_RETURN_VAL(getAttrResult != RESULT_SUCCESS, RESULT_GENERAL_ERROR);
369094332d3Sopenharmony_ci    IF_TRUE_LOGE_AND_RETURN_VAL(uint64Data.len != sizeof(netOrderValue), RESULT_GENERAL_ERROR);
370094332d3Sopenharmony_ci
371094332d3Sopenharmony_ci    *retValue = Ntohl64(netOrderValue);
372094332d3Sopenharmony_ci    return RESULT_SUCCESS;
373094332d3Sopenharmony_ci}
374094332d3Sopenharmony_ci
375094332d3Sopenharmony_ciResultCode SetAttributeUint64(Attribute *attribute, AttributeKey key, const uint64_t value)
376094332d3Sopenharmony_ci{
377094332d3Sopenharmony_ci    IF_TRUE_LOGE_AND_RETURN_VAL(attribute == NULL, RESULT_BAD_PARAM);
378094332d3Sopenharmony_ci
379094332d3Sopenharmony_ci    uint64_t netOrderValue = Htonl64(value);
380094332d3Sopenharmony_ci    ResultCode setAttrResult =
381094332d3Sopenharmony_ci        SetAttributeUint8Array(attribute, key, (Uint8Array){ (uint8_t *)&netOrderValue, sizeof(netOrderValue) });
382094332d3Sopenharmony_ci    IF_TRUE_LOGE_AND_RETURN_VAL(setAttrResult != RESULT_SUCCESS, RESULT_GENERAL_ERROR);
383094332d3Sopenharmony_ci
384094332d3Sopenharmony_ci    return RESULT_SUCCESS;
385094332d3Sopenharmony_ci}
386094332d3Sopenharmony_ci
387094332d3Sopenharmony_ciResultCode GetAttributeLength(const Attribute *attribute, AttributeKey key, uint32_t *len)
388094332d3Sopenharmony_ci{
389094332d3Sopenharmony_ci    IF_TRUE_LOGE_AND_RETURN_VAL(attribute == NULL, RESULT_BAD_PARAM);
390094332d3Sopenharmony_ci    IF_TRUE_LOGE_AND_RETURN_VAL(len == NULL, RESULT_BAD_PARAM);
391094332d3Sopenharmony_ci
392094332d3Sopenharmony_ci    const AttributeImpl *attributePri = (const AttributeImpl *)attribute;
393094332d3Sopenharmony_ci    uint32_t attributeIndex;
394094332d3Sopenharmony_ci    ResultCode getAttrIndexResult = GetAttributeIndex(key, &attributeIndex);
395094332d3Sopenharmony_ci    IF_TRUE_LOGE_AND_RETURN_VAL(getAttrIndexResult != RESULT_SUCCESS, RESULT_GENERAL_ERROR);
396094332d3Sopenharmony_ci
397094332d3Sopenharmony_ci    if (attributePri->values[attributeIndex] == NULL) {
398094332d3Sopenharmony_ci        LOG_ERROR("data is not set");
399094332d3Sopenharmony_ci        return RESULT_GENERAL_ERROR;
400094332d3Sopenharmony_ci    }
401094332d3Sopenharmony_ci    *len = attributePri->values[attributeIndex]->len;
402094332d3Sopenharmony_ci    return RESULT_SUCCESS;
403094332d3Sopenharmony_ci}
404094332d3Sopenharmony_ci
405094332d3Sopenharmony_ciResultCode GetAttributeUint8Array(const Attribute *attributePub, AttributeKey key, Uint8Array *retData)
406094332d3Sopenharmony_ci{
407094332d3Sopenharmony_ci    IF_TRUE_LOGE_AND_RETURN_VAL(attributePub == NULL, RESULT_BAD_PARAM);
408094332d3Sopenharmony_ci    IF_TRUE_LOGE_AND_RETURN_VAL(retData == NULL, RESULT_BAD_PARAM);
409094332d3Sopenharmony_ci    IF_TRUE_LOGE_AND_RETURN_VAL(IS_ARRAY_NULL(*retData), RESULT_BAD_PARAM);
410094332d3Sopenharmony_ci
411094332d3Sopenharmony_ci    const AttributeImpl *attribute = (const AttributeImpl *)attributePub;
412094332d3Sopenharmony_ci
413094332d3Sopenharmony_ci    uint32_t attributeIndex;
414094332d3Sopenharmony_ci    ResultCode getAttrIndexResult = GetAttributeIndex(key, &attributeIndex);
415094332d3Sopenharmony_ci    IF_TRUE_LOGE_AND_RETURN_VAL(getAttrIndexResult != RESULT_SUCCESS, RESULT_GENERAL_ERROR);
416094332d3Sopenharmony_ci
417094332d3Sopenharmony_ci    if (attribute->values[attributeIndex] == NULL) {
418094332d3Sopenharmony_ci        LOG_ERROR("data is not set");
419094332d3Sopenharmony_ci        return RESULT_GENERAL_ERROR;
420094332d3Sopenharmony_ci    }
421094332d3Sopenharmony_ci
422094332d3Sopenharmony_ci    if (attribute->values[attributeIndex]->data != NULL && attribute->values[attributeIndex]->len != 0) {
423094332d3Sopenharmony_ci        errno_t memcpyRet = memcpy_s(retData->data, retData->len, attribute->values[attributeIndex]->data,
424094332d3Sopenharmony_ci            attribute->values[attributeIndex]->len);
425094332d3Sopenharmony_ci        IF_TRUE_LOGE_AND_RETURN_VAL(memcpyRet != EOK, RESULT_GENERAL_ERROR);
426094332d3Sopenharmony_ci        retData->len = attribute->values[attributeIndex]->len;
427094332d3Sopenharmony_ci    } else {
428094332d3Sopenharmony_ci        LOG_INFO("the current data is an empty array");
429094332d3Sopenharmony_ci        retData->len = 0;
430094332d3Sopenharmony_ci    }
431094332d3Sopenharmony_ci
432094332d3Sopenharmony_ci    return RESULT_SUCCESS;
433094332d3Sopenharmony_ci}
434094332d3Sopenharmony_ci
435094332d3Sopenharmony_ciResultCode SetAttributeUint8Array(Attribute *attributePub, AttributeKey key, const Uint8Array data)
436094332d3Sopenharmony_ci{
437094332d3Sopenharmony_ci    IF_TRUE_LOGE_AND_RETURN_VAL(attributePub == NULL, RESULT_BAD_PARAM);
438094332d3Sopenharmony_ci    IF_TRUE_LOGE_AND_RETURN_VAL(!IS_ARRAY_VALID(data), RESULT_BAD_PARAM);
439094332d3Sopenharmony_ci
440094332d3Sopenharmony_ci    AttributeImpl *attribute = (AttributeImpl *)attributePub;
441094332d3Sopenharmony_ci
442094332d3Sopenharmony_ci    uint32_t attributeIndex;
443094332d3Sopenharmony_ci    ResultCode getAttrIndexResult = GetAttributeIndex(key, &attributeIndex);
444094332d3Sopenharmony_ci    IF_TRUE_LOGE_AND_RETURN_VAL(getAttrIndexResult != RESULT_SUCCESS, RESULT_GENERAL_ERROR);
445094332d3Sopenharmony_ci
446094332d3Sopenharmony_ci    DestroyUint8Array(&attribute->values[attributeIndex]);
447094332d3Sopenharmony_ci    attribute->values[attributeIndex] = CreateUint8ArrayByData(data.data, data.len);
448094332d3Sopenharmony_ci    if (attribute->values[attributeIndex] == NULL) {
449094332d3Sopenharmony_ci        LOG_ERROR("CreateUint8ArrayByData fail");
450094332d3Sopenharmony_ci        return RESULT_GENERAL_ERROR;
451094332d3Sopenharmony_ci    }
452094332d3Sopenharmony_ci
453094332d3Sopenharmony_ci    return RESULT_SUCCESS;
454094332d3Sopenharmony_ci}
455094332d3Sopenharmony_ci
456094332d3Sopenharmony_ciResultCode GetAttributeUint64Array(const Attribute *attribute, AttributeKey key, Uint64Array *retData)
457094332d3Sopenharmony_ci{
458094332d3Sopenharmony_ci    IF_TRUE_LOGE_AND_RETURN_VAL(attribute == NULL, RESULT_BAD_PARAM);
459094332d3Sopenharmony_ci    IF_TRUE_LOGE_AND_RETURN_VAL(retData == NULL, RESULT_BAD_PARAM);
460094332d3Sopenharmony_ci    IF_TRUE_LOGE_AND_RETURN_VAL(IS_ARRAY_NULL(*retData), RESULT_BAD_PARAM);
461094332d3Sopenharmony_ci
462094332d3Sopenharmony_ci    Uint8Array uint64ArrayData = { (uint8_t *)retData->data, retData->len * sizeof(uint64_t) };
463094332d3Sopenharmony_ci    ResultCode getAttrResult = GetAttributeUint8Array(attribute, key, &uint64ArrayData);
464094332d3Sopenharmony_ci    IF_TRUE_LOGE_AND_RETURN_VAL(getAttrResult != RESULT_SUCCESS, RESULT_GENERAL_ERROR);
465094332d3Sopenharmony_ci    if (uint64ArrayData.len % sizeof(uint64_t) != 0) {
466094332d3Sopenharmony_ci        LOG_ERROR("uint8 length %u is incorrect", uint64ArrayData.len);
467094332d3Sopenharmony_ci        return RESULT_GENERAL_ERROR;
468094332d3Sopenharmony_ci    }
469094332d3Sopenharmony_ci    Ntohl64Array(retData);
470094332d3Sopenharmony_ci
471094332d3Sopenharmony_ci    retData->len = uint64ArrayData.len / sizeof(uint64_t);
472094332d3Sopenharmony_ci    return RESULT_SUCCESS;
473094332d3Sopenharmony_ci}
474094332d3Sopenharmony_ci
475094332d3Sopenharmony_ciResultCode SetAttributeUint64Array(Attribute *attribute, AttributeKey key, const Uint64Array data)
476094332d3Sopenharmony_ci{
477094332d3Sopenharmony_ci    IF_TRUE_LOGE_AND_RETURN_VAL(attribute == NULL, RESULT_BAD_PARAM);
478094332d3Sopenharmony_ci    IF_TRUE_LOGE_AND_RETURN_VAL(!IS_ARRAY_VALID(data), RESULT_BAD_PARAM);
479094332d3Sopenharmony_ci
480094332d3Sopenharmony_ci    Uint64Array *netOrderData = CreateUint64ArrayByData(data.data, data.len);
481094332d3Sopenharmony_ci    IF_TRUE_LOGE_AND_RETURN_VAL(netOrderData == NULL, RESULT_GENERAL_ERROR);
482094332d3Sopenharmony_ci
483094332d3Sopenharmony_ci    ResultCode result = RESULT_GENERAL_ERROR;
484094332d3Sopenharmony_ci    do {
485094332d3Sopenharmony_ci        Htonl64Array(netOrderData);
486094332d3Sopenharmony_ci        if (netOrderData->len > UINT32_MAX / sizeof(uint64_t)) {
487094332d3Sopenharmony_ci            LOG_ERROR("netOrderData->len is invalid");
488094332d3Sopenharmony_ci            break;
489094332d3Sopenharmony_ci        }
490094332d3Sopenharmony_ci        result = SetAttributeUint8Array(attribute, key,
491094332d3Sopenharmony_ci            (Uint8Array) { (uint8_t *)netOrderData->data, netOrderData->len * sizeof(uint64_t) });
492094332d3Sopenharmony_ci        if (result != RESULT_SUCCESS) {
493094332d3Sopenharmony_ci            LOG_ERROR("SetAttributeUint8Array fail");
494094332d3Sopenharmony_ci            break;
495094332d3Sopenharmony_ci        }
496094332d3Sopenharmony_ci    } while (0);
497094332d3Sopenharmony_ci
498094332d3Sopenharmony_ci    DestroyUint64Array(&netOrderData);
499094332d3Sopenharmony_ci    return result;
500094332d3Sopenharmony_ci}
501