1 /*
2 * Copyright (C) 2023-2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "attribute.h"
17
18 #include "securec.h"
19
20 #include "adaptor_log.h"
21 #include "adaptor_memory.h"
22
23 #ifdef IAM_TEST_ENABLE
24 #define IAM_STATIC
25 #else
26 #define IAM_STATIC static
27 #endif
28
29 AttributeKey g_attributeKeyArray[] = {
30 ATTR_RESULT_CODE,
31 ATTR_SIGNATURE,
32 ATTR_TEMPLATE_ID,
33 ATTR_REMAIN_ATTEMPTS,
34 ATTR_LOCKOUT_DURATION,
35 ATTR_SCHEDULE_ID,
36 ATTR_DATA,
37 ATTR_PIN_SUB_TYPE,
38 ATTR_ACL,
39 ATTR_TIME_STAMP,
40 ATTR_ROOT_SECRET,
41 ATTR_ROOT,
42 ATTR_LOCAL_UDID,
43 ATTR_PEER_UDID,
44 ATTR_PUBLIC_KEY,
45 ATTR_CHALLENGE,
46 PIN_ATTR_MSG_ID,
47 PIN_ATTR_ALGO_VERSION,
48 PIN_ATTR_ALGO_PARAM,
49 PIN_ATTR_KEK_SALT,
50 PIN_ATTR_KEK_IV,
51 PIN_ATTR_KEK_SECRET,
52 PIN_ATTR_KEK_TAG,
53 };
54
55 #define ARRAY_LENGTH(array) (uint32_t)(sizeof(array) / sizeof((array)[0]))
56 #define ATTRIBUTE_LEN (ARRAY_LENGTH(g_attributeKeyArray))
57
58 typedef struct {
59 Uint8Array *values[ATTRIBUTE_LEN];
60 } AttributeImpl;
61
Ntohl32(uint32_t in)62 IAM_STATIC uint32_t Ntohl32(uint32_t in)
63 {
64 return in;
65 }
66
Htonl32(uint32_t in)67 IAM_STATIC uint32_t Htonl32(uint32_t in)
68 {
69 return in;
70 }
71
Ntohl64(uint64_t in)72 IAM_STATIC uint64_t Ntohl64(uint64_t in)
73 {
74 return in;
75 }
76
Htonl64(uint64_t in)77 IAM_STATIC uint64_t Htonl64(uint64_t in)
78 {
79 return in;
80 }
81
Ntohl64Array(Uint64Array * array)82 IAM_STATIC void Ntohl64Array(Uint64Array *array)
83 {
84 for (uint32_t i = 0; i < array->len; i++) {
85 array->data[i] = Ntohl64(array->data[i]);
86 }
87 }
88
Htonl64Array(Uint64Array * array)89 IAM_STATIC void Htonl64Array(Uint64Array *array)
90 {
91 for (uint32_t i = 0; i < array->len; i++) {
92 array->data[i] = Htonl64(array->data[i]);
93 }
94 }
95
GetAttributeIndex(AttributeKey key,uint32_t * index)96 IAM_STATIC ResultCode GetAttributeIndex(AttributeKey key, uint32_t *index)
97 {
98 for (uint32_t i = 0; i < ATTRIBUTE_LEN; ++i) {
99 if (g_attributeKeyArray[i] == key) {
100 *index = i;
101 return RESULT_SUCCESS;
102 }
103 }
104
105 return RESULT_GENERAL_ERROR;
106 }
107
ReadDataFromMsg(const Uint8Array msg,uint32_t * readIndex,Uint8Array * retData)108 IAM_STATIC ResultCode ReadDataFromMsg(const Uint8Array msg, uint32_t *readIndex, Uint8Array *retData)
109 {
110 if (msg.len <= *readIndex) {
111 LOG_ERROR("msg length is not enough");
112 return RESULT_GENERAL_ERROR;
113 }
114
115 if (msg.len - *readIndex < retData->len) {
116 LOG_ERROR("remain data length is not enough");
117 return RESULT_GENERAL_ERROR;
118 }
119
120 if (memcpy_s(retData->data, retData->len, msg.data + *readIndex, retData->len) != EOK) {
121 LOG_ERROR("memcpy_s fail");
122 return RESULT_GENERAL_ERROR;
123 }
124
125 *readIndex += retData->len;
126 return RESULT_SUCCESS;
127 }
128
ReadUint32FromMsg(const Uint8Array msg,uint32_t * readIndex,uint32_t * retValue)129 IAM_STATIC ResultCode ReadUint32FromMsg(const Uint8Array msg, uint32_t *readIndex, uint32_t *retValue)
130 {
131 uint32_t netOrderValue;
132 Uint8Array uint8Data = { (uint8_t *)&netOrderValue, sizeof(netOrderValue) };
133 ResultCode result = ReadDataFromMsg(msg, readIndex, &uint8Data);
134 if (result != RESULT_SUCCESS) {
135 LOG_ERROR("read data fail");
136 return RESULT_GENERAL_ERROR;
137 }
138
139 *retValue = Ntohl32(netOrderValue);
140 return RESULT_SUCCESS;
141 }
142
WriteDataToMsg(Uint8Array * msg,uint32_t * writeIndex,const Uint8Array data)143 IAM_STATIC ResultCode WriteDataToMsg(Uint8Array *msg, uint32_t *writeIndex, const Uint8Array data)
144 {
145 if (msg->len <= *writeIndex) {
146 LOG_ERROR("msg length is not enough");
147 return RESULT_GENERAL_ERROR;
148 }
149
150 if (msg->len - *writeIndex < data.len) {
151 LOG_ERROR("remain data size is not enough");
152 return RESULT_GENERAL_ERROR;
153 }
154
155 if (memcpy_s(msg->data + *writeIndex, msg->len - *writeIndex, data.data, data.len) != EOK) {
156 LOG_ERROR("memcpy_s fail");
157 return RESULT_GENERAL_ERROR;
158 }
159
160 *writeIndex += data.len;
161 return RESULT_SUCCESS;
162 }
163
WriteUInt32ToMsg(Uint8Array * msg,uint32_t * writeIndex,uint32_t value)164 IAM_STATIC ResultCode WriteUInt32ToMsg(Uint8Array *msg, uint32_t *writeIndex, uint32_t value)
165 {
166 uint32_t netOrderValue = Htonl32(value);
167 ResultCode result =
168 WriteDataToMsg(msg, writeIndex, (Uint8Array){ (uint8_t *)&netOrderValue, sizeof(netOrderValue) });
169 if (result != RESULT_SUCCESS) {
170 LOG_ERROR("write data fail");
171 return RESULT_GENERAL_ERROR;
172 }
173 return RESULT_SUCCESS;
174 }
175
CheckAddReadIndex(const Uint8Array msg,uint32_t * readIndex,uint32_t length)176 IAM_STATIC ResultCode CheckAddReadIndex(const Uint8Array msg, uint32_t *readIndex, uint32_t length)
177 {
178 if (msg.len <= (*readIndex)) {
179 LOG_ERROR("msg length is not enough");
180 return RESULT_GENERAL_ERROR;
181 }
182
183 if ((msg.len - (*readIndex)) < length) {
184 LOG_ERROR("remain data length is not enough");
185 return RESULT_GENERAL_ERROR;
186 }
187
188 (*readIndex) += length;
189 return RESULT_SUCCESS;
190 }
191
ParseAttributeSerializedMsgInner(Attribute * attribute,const Uint8Array msg,const Uint8Array * readBuffer)192 IAM_STATIC ResultCode ParseAttributeSerializedMsgInner(Attribute *attribute, const Uint8Array msg,
193 const Uint8Array *readBuffer)
194 {
195 uint32_t readIndex = 0;
196 while (readIndex < msg.len) {
197 uint32_t type;
198 ResultCode readTypeResult = ReadUint32FromMsg(msg, &readIndex, &type);
199 IF_TRUE_LOGE_AND_RETURN_VAL(readTypeResult != RESULT_SUCCESS, RESULT_GENERAL_ERROR);
200
201 uint32_t length;
202 ResultCode readLengthResult = ReadUint32FromMsg(msg, &readIndex, &length);
203 IF_TRUE_LOGE_AND_RETURN_VAL(readLengthResult != RESULT_SUCCESS, RESULT_GENERAL_ERROR);
204
205 if (length > readBuffer->len) {
206 LOG_INFO("attribute:%{public}u too long:%{public}u, skip", type, length);
207 ResultCode checkAddReadIndexResult = CheckAddReadIndex(msg, &readIndex, length);
208 IF_TRUE_LOGE_AND_RETURN_VAL(checkAddReadIndexResult != RESULT_SUCCESS, RESULT_GENERAL_ERROR);
209 continue;
210 }
211
212 Uint8Array readData = { readBuffer->data, length };
213 if (length > 0) {
214 ResultCode readDataResult = ReadDataFromMsg(msg, &readIndex, &readData);
215 IF_TRUE_LOGE_AND_RETURN_VAL(readDataResult != RESULT_SUCCESS, RESULT_GENERAL_ERROR);
216 }
217
218 uint32_t attributeIndex;
219 if (GetAttributeIndex(type, &attributeIndex) != RESULT_SUCCESS) {
220 LOG_INFO("attribute:%{public}u not found, skip", type);
221 continue;
222 }
223
224 ResultCode setAttrResult = SetAttributeUint8Array(attribute, type, readData);
225 IF_TRUE_LOGE_AND_RETURN_VAL(setAttrResult != RESULT_SUCCESS, RESULT_GENERAL_ERROR);
226 }
227
228 return RESULT_SUCCESS;
229 }
230
ParseAttributeSerializedMsg(Attribute * attribute,const Uint8Array msg)231 IAM_STATIC ResultCode ParseAttributeSerializedMsg(Attribute *attribute, const Uint8Array msg)
232 {
233 Uint8Array *readBuffer = CreateUint8ArrayBySize(MAX_EXECUTOR_MSG_LEN);
234 IF_TRUE_LOGE_AND_RETURN_VAL(readBuffer == NULL, RESULT_GENERAL_ERROR);
235
236 ResultCode result = ParseAttributeSerializedMsgInner(attribute, msg, readBuffer);
237 if (result != RESULT_SUCCESS) {
238 LOG_ERROR("ParseAttributeSerializedMsgInner fail");
239 }
240 DestroyUint8Array(&readBuffer);
241
242 return result;
243 }
244
CreateEmptyAttribute(void)245 Attribute *CreateEmptyAttribute(void)
246 {
247 AttributeImpl *attribute = Malloc(sizeof(AttributeImpl));
248 IF_TRUE_LOGE_AND_RETURN_VAL(attribute == NULL, NULL);
249 (void)memset_s(attribute, sizeof(AttributeImpl), 0, sizeof(AttributeImpl));
250
251 return attribute;
252 }
253
CreateAttributeFromSerializedMsg(const Uint8Array msg)254 Attribute *CreateAttributeFromSerializedMsg(const Uint8Array msg)
255 {
256 IF_TRUE_LOGE_AND_RETURN_VAL(IS_ARRAY_NULL(msg), NULL);
257
258 Attribute *attribute = CreateEmptyAttribute();
259 if (attribute == NULL) {
260 LOG_ERROR("CreateEmptyAttribute failed");
261 return NULL;
262 }
263
264 ResultCode result = ParseAttributeSerializedMsg(attribute, msg);
265 if (result != RESULT_SUCCESS) {
266 LOG_ERROR("ParseAttributeSerializedMsg failed");
267 FreeAttribute((Attribute **)&attribute);
268 return NULL;
269 }
270
271 return attribute;
272 }
273
GetAttributeSerializedMsg(const Attribute * attributePublic,Uint8Array * retMsg)274 ResultCode GetAttributeSerializedMsg(const Attribute *attributePublic, Uint8Array *retMsg)
275 {
276 IF_TRUE_LOGE_AND_RETURN_VAL(attributePublic == NULL, RESULT_BAD_PARAM);
277 IF_TRUE_LOGE_AND_RETURN_VAL(retMsg == NULL, RESULT_BAD_PARAM);
278 IF_TRUE_LOGE_AND_RETURN_VAL(IS_ARRAY_NULL(*retMsg), RESULT_BAD_PARAM);
279
280 const AttributeImpl *attribute = (const AttributeImpl *)attributePublic;
281 uint32_t writeIndex = 0;
282 for (uint32_t i = 0; i < ATTRIBUTE_LEN; i++) {
283 Uint8Array *array = attribute->values[i];
284 if (array == NULL) {
285 continue;
286 }
287
288 ResultCode writeTypeResult = WriteUInt32ToMsg(retMsg, &writeIndex, g_attributeKeyArray[i]);
289 IF_TRUE_LOGE_AND_RETURN_VAL(writeTypeResult != RESULT_SUCCESS, RESULT_GENERAL_ERROR);
290
291 ResultCode writeLengthResult = WriteUInt32ToMsg(retMsg, &writeIndex, array->len);
292 IF_TRUE_LOGE_AND_RETURN_VAL(writeLengthResult != RESULT_SUCCESS, RESULT_GENERAL_ERROR);
293
294 if (array->len == 0) {
295 continue;
296 }
297 ResultCode writeDataResult =
298 WriteDataToMsg(retMsg, &writeIndex, *array);
299 IF_TRUE_LOGE_AND_RETURN_VAL(writeDataResult != RESULT_SUCCESS, RESULT_GENERAL_ERROR);
300 }
301
302 retMsg->len = writeIndex;
303 return RESULT_SUCCESS;
304 }
305
FreeAttribute(Attribute ** attribute)306 void FreeAttribute(Attribute **attribute)
307 {
308 IF_TRUE_LOGE_AND_RETURN(attribute == NULL);
309 IF_TRUE_LOGE_AND_RETURN(*attribute == NULL);
310 AttributeImpl *impl = (AttributeImpl *)*attribute;
311 for (uint32_t i = 0; i < ATTRIBUTE_LEN; ++i) {
312 DestroyUint8Array(&impl->values[i]);
313 }
314
315 IAM_FREE_AND_SET_NULL(*attribute);
316 }
317
GetAttributeUint32(const Attribute * attribute,AttributeKey key,uint32_t * value)318 ResultCode GetAttributeUint32(const Attribute *attribute, AttributeKey key, uint32_t *value)
319 {
320 IF_TRUE_LOGE_AND_RETURN_VAL(attribute == NULL, RESULT_BAD_PARAM);
321 IF_TRUE_LOGE_AND_RETURN_VAL(value == NULL, RESULT_BAD_PARAM);
322
323 uint32_t netOrderValue;
324 Uint8Array uint32Data = { (uint8_t *)&netOrderValue, sizeof(netOrderValue) };
325 ResultCode getAttrResult = GetAttributeUint8Array(attribute, key, &uint32Data);
326 IF_TRUE_LOGE_AND_RETURN_VAL(getAttrResult != RESULT_SUCCESS, RESULT_GENERAL_ERROR);
327 IF_TRUE_LOGE_AND_RETURN_VAL(uint32Data.len != sizeof(netOrderValue), RESULT_GENERAL_ERROR);
328
329 *value = Ntohl32(netOrderValue);
330 return RESULT_SUCCESS;
331 }
332
SetAttributeUint32(Attribute * attribute,AttributeKey key,const uint32_t value)333 ResultCode SetAttributeUint32(Attribute *attribute, AttributeKey key, const uint32_t value)
334 {
335 IF_TRUE_LOGE_AND_RETURN_VAL(attribute == NULL, RESULT_BAD_PARAM);
336
337 uint32_t netOrderValue = Htonl32(value);
338 ResultCode result =
339 SetAttributeUint8Array(attribute, key, (Uint8Array) { (uint8_t *)&netOrderValue, sizeof(netOrderValue) });
340 IF_TRUE_LOGE_AND_RETURN_VAL(result != RESULT_SUCCESS, RESULT_GENERAL_ERROR);
341
342 return result;
343 }
344
GetAttributeInt32(const Attribute * attribute,AttributeKey key,int32_t * retValue)345 ResultCode GetAttributeInt32(const Attribute *attribute, AttributeKey key, int32_t *retValue)
346 {
347 IF_TRUE_LOGE_AND_RETURN_VAL(attribute == NULL, RESULT_BAD_PARAM);
348 IF_TRUE_LOGE_AND_RETURN_VAL(retValue == NULL, RESULT_BAD_PARAM);
349
350 return GetAttributeUint32(attribute, key, (uint32_t *)retValue);
351 }
352
SetAttributeInt32(Attribute * attribute,AttributeKey key,const int32_t value)353 ResultCode SetAttributeInt32(Attribute *attribute, AttributeKey key, const int32_t value)
354 {
355 IF_TRUE_LOGE_AND_RETURN_VAL(attribute == NULL, RESULT_BAD_PARAM);
356
357 return SetAttributeUint32(attribute, key, (uint32_t)value);
358 }
359
GetAttributeUint64(const Attribute * attribute,AttributeKey key,uint64_t * retValue)360 ResultCode GetAttributeUint64(const Attribute *attribute, AttributeKey key, uint64_t *retValue)
361 {
362 IF_TRUE_LOGE_AND_RETURN_VAL(attribute == NULL, RESULT_BAD_PARAM);
363 IF_TRUE_LOGE_AND_RETURN_VAL(retValue == NULL, RESULT_BAD_PARAM);
364
365 uint64_t netOrderValue;
366 Uint8Array uint64Data = { (uint8_t *)&netOrderValue, sizeof(netOrderValue) };
367 ResultCode getAttrResult = GetAttributeUint8Array(attribute, key, &uint64Data);
368 IF_TRUE_LOGE_AND_RETURN_VAL(getAttrResult != RESULT_SUCCESS, RESULT_GENERAL_ERROR);
369 IF_TRUE_LOGE_AND_RETURN_VAL(uint64Data.len != sizeof(netOrderValue), RESULT_GENERAL_ERROR);
370
371 *retValue = Ntohl64(netOrderValue);
372 return RESULT_SUCCESS;
373 }
374
SetAttributeUint64(Attribute * attribute,AttributeKey key,const uint64_t value)375 ResultCode SetAttributeUint64(Attribute *attribute, AttributeKey key, const uint64_t value)
376 {
377 IF_TRUE_LOGE_AND_RETURN_VAL(attribute == NULL, RESULT_BAD_PARAM);
378
379 uint64_t netOrderValue = Htonl64(value);
380 ResultCode setAttrResult =
381 SetAttributeUint8Array(attribute, key, (Uint8Array){ (uint8_t *)&netOrderValue, sizeof(netOrderValue) });
382 IF_TRUE_LOGE_AND_RETURN_VAL(setAttrResult != RESULT_SUCCESS, RESULT_GENERAL_ERROR);
383
384 return RESULT_SUCCESS;
385 }
386
GetAttributeLength(const Attribute * attribute,AttributeKey key,uint32_t * len)387 ResultCode GetAttributeLength(const Attribute *attribute, AttributeKey key, uint32_t *len)
388 {
389 IF_TRUE_LOGE_AND_RETURN_VAL(attribute == NULL, RESULT_BAD_PARAM);
390 IF_TRUE_LOGE_AND_RETURN_VAL(len == NULL, RESULT_BAD_PARAM);
391
392 const AttributeImpl *attributePri = (const AttributeImpl *)attribute;
393 uint32_t attributeIndex;
394 ResultCode getAttrIndexResult = GetAttributeIndex(key, &attributeIndex);
395 IF_TRUE_LOGE_AND_RETURN_VAL(getAttrIndexResult != RESULT_SUCCESS, RESULT_GENERAL_ERROR);
396
397 if (attributePri->values[attributeIndex] == NULL) {
398 LOG_ERROR("data is not set");
399 return RESULT_GENERAL_ERROR;
400 }
401 *len = attributePri->values[attributeIndex]->len;
402 return RESULT_SUCCESS;
403 }
404
GetAttributeUint8Array(const Attribute * attributePub,AttributeKey key,Uint8Array * retData)405 ResultCode GetAttributeUint8Array(const Attribute *attributePub, AttributeKey key, Uint8Array *retData)
406 {
407 IF_TRUE_LOGE_AND_RETURN_VAL(attributePub == NULL, RESULT_BAD_PARAM);
408 IF_TRUE_LOGE_AND_RETURN_VAL(retData == NULL, RESULT_BAD_PARAM);
409 IF_TRUE_LOGE_AND_RETURN_VAL(IS_ARRAY_NULL(*retData), RESULT_BAD_PARAM);
410
411 const AttributeImpl *attribute = (const AttributeImpl *)attributePub;
412
413 uint32_t attributeIndex;
414 ResultCode getAttrIndexResult = GetAttributeIndex(key, &attributeIndex);
415 IF_TRUE_LOGE_AND_RETURN_VAL(getAttrIndexResult != RESULT_SUCCESS, RESULT_GENERAL_ERROR);
416
417 if (attribute->values[attributeIndex] == NULL) {
418 LOG_ERROR("data is not set");
419 return RESULT_GENERAL_ERROR;
420 }
421
422 if (attribute->values[attributeIndex]->data != NULL && attribute->values[attributeIndex]->len != 0) {
423 errno_t memcpyRet = memcpy_s(retData->data, retData->len, attribute->values[attributeIndex]->data,
424 attribute->values[attributeIndex]->len);
425 IF_TRUE_LOGE_AND_RETURN_VAL(memcpyRet != EOK, RESULT_GENERAL_ERROR);
426 retData->len = attribute->values[attributeIndex]->len;
427 } else {
428 LOG_INFO("the current data is an empty array");
429 retData->len = 0;
430 }
431
432 return RESULT_SUCCESS;
433 }
434
SetAttributeUint8Array(Attribute * attributePub,AttributeKey key,const Uint8Array data)435 ResultCode SetAttributeUint8Array(Attribute *attributePub, AttributeKey key, const Uint8Array data)
436 {
437 IF_TRUE_LOGE_AND_RETURN_VAL(attributePub == NULL, RESULT_BAD_PARAM);
438 IF_TRUE_LOGE_AND_RETURN_VAL(!IS_ARRAY_VALID(data), RESULT_BAD_PARAM);
439
440 AttributeImpl *attribute = (AttributeImpl *)attributePub;
441
442 uint32_t attributeIndex;
443 ResultCode getAttrIndexResult = GetAttributeIndex(key, &attributeIndex);
444 IF_TRUE_LOGE_AND_RETURN_VAL(getAttrIndexResult != RESULT_SUCCESS, RESULT_GENERAL_ERROR);
445
446 DestroyUint8Array(&attribute->values[attributeIndex]);
447 attribute->values[attributeIndex] = CreateUint8ArrayByData(data.data, data.len);
448 if (attribute->values[attributeIndex] == NULL) {
449 LOG_ERROR("CreateUint8ArrayByData fail");
450 return RESULT_GENERAL_ERROR;
451 }
452
453 return RESULT_SUCCESS;
454 }
455
GetAttributeUint64Array(const Attribute * attribute,AttributeKey key,Uint64Array * retData)456 ResultCode GetAttributeUint64Array(const Attribute *attribute, AttributeKey key, Uint64Array *retData)
457 {
458 IF_TRUE_LOGE_AND_RETURN_VAL(attribute == NULL, RESULT_BAD_PARAM);
459 IF_TRUE_LOGE_AND_RETURN_VAL(retData == NULL, RESULT_BAD_PARAM);
460 IF_TRUE_LOGE_AND_RETURN_VAL(IS_ARRAY_NULL(*retData), RESULT_BAD_PARAM);
461
462 Uint8Array uint64ArrayData = { (uint8_t *)retData->data, retData->len * sizeof(uint64_t) };
463 ResultCode getAttrResult = GetAttributeUint8Array(attribute, key, &uint64ArrayData);
464 IF_TRUE_LOGE_AND_RETURN_VAL(getAttrResult != RESULT_SUCCESS, RESULT_GENERAL_ERROR);
465 if (uint64ArrayData.len % sizeof(uint64_t) != 0) {
466 LOG_ERROR("uint8 length %u is incorrect", uint64ArrayData.len);
467 return RESULT_GENERAL_ERROR;
468 }
469 Ntohl64Array(retData);
470
471 retData->len = uint64ArrayData.len / sizeof(uint64_t);
472 return RESULT_SUCCESS;
473 }
474
SetAttributeUint64Array(Attribute * attribute,AttributeKey key,const Uint64Array data)475 ResultCode SetAttributeUint64Array(Attribute *attribute, AttributeKey key, const Uint64Array data)
476 {
477 IF_TRUE_LOGE_AND_RETURN_VAL(attribute == NULL, RESULT_BAD_PARAM);
478 IF_TRUE_LOGE_AND_RETURN_VAL(!IS_ARRAY_VALID(data), RESULT_BAD_PARAM);
479
480 Uint64Array *netOrderData = CreateUint64ArrayByData(data.data, data.len);
481 IF_TRUE_LOGE_AND_RETURN_VAL(netOrderData == NULL, RESULT_GENERAL_ERROR);
482
483 ResultCode result = RESULT_GENERAL_ERROR;
484 do {
485 Htonl64Array(netOrderData);
486 if (netOrderData->len > UINT32_MAX / sizeof(uint64_t)) {
487 LOG_ERROR("netOrderData->len is invalid");
488 break;
489 }
490 result = SetAttributeUint8Array(attribute, key,
491 (Uint8Array) { (uint8_t *)netOrderData->data, netOrderData->len * sizeof(uint64_t) });
492 if (result != RESULT_SUCCESS) {
493 LOG_ERROR("SetAttributeUint8Array fail");
494 break;
495 }
496 } while (0);
497
498 DestroyUint64Array(&netOrderData);
499 return result;
500 }
501