1 /*
2 * This file is part of the openHiTLS project.
3 *
4 * openHiTLS is licensed under the Mulan PSL v2.
5 * You can use this software according to the terms and conditions of the Mulan PSL v2.
6 * You may obtain a copy of Mulan PSL v2 at:
7 *
8 * http://license.coscl.org.cn/MulanPSL2
9 *
10 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13 * See the Mulan PSL v2 for more details.
14 */
15
16 #include "hitls_build.h"
17 #ifdef HITLS_BSL_TLV
18
19 #include <stdint.h>
20 #include "securec.h"
21 #include "bsl_errno.h"
22 #include "bsl_bytes.h"
23 #include "bsl_log_internal.h"
24 #include "bsl_err_internal.h"
25 #include "bsl_binlog_id.h"
26 #include "tlv.h"
27
BSL_TLV_Pack(const BSL_Tlv * tlv,uint8_t * buffer,uint32_t bufLen,uint32_t * usedLen)28 int32_t BSL_TLV_Pack(const BSL_Tlv *tlv, uint8_t *buffer, uint32_t bufLen, uint32_t *usedLen)
29 {
30 uint8_t *curPos = buffer;
31 if ((bufLen < TLV_HEADER_LENGTH) || (tlv->length > bufLen - TLV_HEADER_LENGTH)) {
32 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05013, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
33 "TLV build error: bufLen = %u is not enough for tlv length = %u, tlv type = 0x%x.",
34 bufLen, tlv->length, tlv->type, 0);
35 BSL_ERR_PUSH_ERROR(BSL_TLV_ERR_BAD_PARAM);
36 return BSL_TLV_ERR_BAD_PARAM;
37 }
38
39 /* Write the TLV type */
40 BSL_Uint32ToByte(tlv->type, curPos);
41 curPos += sizeof(uint32_t);
42 /* Write the TLV length */
43 BSL_Uint32ToByte(tlv->length, curPos);
44 curPos += sizeof(uint32_t);
45 /* Write TLV data */
46 if (memcpy_s(curPos, bufLen - TLV_HEADER_LENGTH, tlv->value, tlv->length) != EOK) {
47 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05014, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
48 "TLV build error: write tlv value fail, bufLen = %u, tlv length = %u, tlv type = 0x%x.",
49 bufLen, tlv->length, tlv->type, 0);
50 BSL_ERR_PUSH_ERROR(BSL_MEMCPY_FAIL);
51 return BSL_MEMCPY_FAIL;
52 }
53
54 *usedLen = TLV_HEADER_LENGTH + tlv->length;
55 return BSL_SUCCESS;
56 }
57
TLV_ParseHeader(const uint8_t * data,uint32_t dataLen,uint32_t * type,uint32_t * length)58 static int32_t TLV_ParseHeader(const uint8_t *data, uint32_t dataLen, uint32_t *type, uint32_t *length)
59 {
60 const uint8_t *curPos = data;
61 /* Parse the TLV type */
62 uint32_t tlvType = BSL_ByteToUint32(curPos);
63 curPos += sizeof(uint32_t);
64 /* Parse the TLV length */
65 uint32_t tlvLen = BSL_ByteToUint32(curPos);
66 if (tlvLen > dataLen - TLV_HEADER_LENGTH) {
67 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05015, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
68 "Check TLV header error: dataLen = %u, tlv length = %u, tlv type = 0x%x.", dataLen, tlvLen, tlvType, 0);
69 BSL_ERR_PUSH_ERROR(BSL_TLV_ERR_BAD_PARAM);
70 return BSL_TLV_ERR_BAD_PARAM;
71 }
72
73 *type = tlvType;
74 *length = tlvLen;
75 return BSL_SUCCESS;
76 }
77
BSL_TLV_Parse(uint32_t wantType,const uint8_t * data,uint32_t dataLen,BSL_Tlv * tlv,uint32_t * readLen)78 int32_t BSL_TLV_Parse(uint32_t wantType, const uint8_t *data, uint32_t dataLen, BSL_Tlv *tlv, uint32_t *readLen)
79 {
80 int32_t ret;
81 const uint8_t *curPos = data;
82 uint32_t remainLen = dataLen;
83 uint32_t type;
84 uint32_t length;
85 while (remainLen >= TLV_HEADER_LENGTH) {
86 /* Parse the TLV type and length */
87 ret = TLV_ParseHeader(curPos, remainLen, &type, &length);
88 if (ret != BSL_SUCCESS) {
89 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05016, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
90 "Parse TLV error: tlv header illegal.", 0, 0, 0, 0);
91 return ret;
92 }
93 remainLen -= (TLV_HEADER_LENGTH + length);
94
95 /* The TLV type matches the expected type */
96 if (wantType == type) {
97 /* Parse the TLV data */
98 if (memcpy_s(tlv->value, tlv->length, curPos + TLV_HEADER_LENGTH, length) != EOK) {
99 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05017, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
100 "Parse TLV error: write tlv value fail, bufLen = %u, tlv length = %u, tlv type = 0x%x.",
101 tlv->length, length, type, 0);
102 BSL_ERR_PUSH_ERROR(BSL_MEMCPY_FAIL);
103 return BSL_MEMCPY_FAIL;
104 }
105 tlv->type = type;
106 tlv->length = length;
107 *readLen = dataLen - remainLen;
108 return BSL_SUCCESS;
109 }
110 /* The TLV type does not match the expected type. Continue to parse the next TLV. */
111 curPos += (TLV_HEADER_LENGTH + length);
112 }
113 /* No matched TLV found */
114 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05018, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
115 "Parse TLV error: no want type(0x%x), dataLen = %u.", wantType, dataLen, 0, 0);
116 BSL_ERR_PUSH_ERROR(BSL_TLV_ERR_NO_WANT_TYPE);
117 return BSL_TLV_ERR_NO_WANT_TYPE;
118 }
119
BSL_TLV_FindValuePos(uint32_t wantType,const uint8_t * data,uint32_t dataLen,uint32_t * offset,uint32_t * length)120 int32_t BSL_TLV_FindValuePos(uint32_t wantType, const uint8_t *data, uint32_t dataLen,
121 uint32_t *offset, uint32_t *length)
122 {
123 int32_t ret;
124 const uint8_t *curPos = data;
125 uint32_t remainLen = dataLen;
126 uint32_t type;
127 while (remainLen > TLV_HEADER_LENGTH) {
128 /* Parse the TLV type and length */
129 ret = TLV_ParseHeader(curPos, remainLen, &type, length);
130 if (ret != BSL_SUCCESS) {
131 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05019, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
132 "Find TLV error: tlv header illegal.", 0, 0, 0, 0);
133 return ret;
134 }
135 /* The TLV type matches the expected type */
136 if (wantType == type) {
137 *offset = dataLen - remainLen + TLV_HEADER_LENGTH;
138 return BSL_SUCCESS;
139 }
140 /* The TLV type does not match the expected type. Continue to parse the next TLV. */
141 curPos += (TLV_HEADER_LENGTH + *length);
142 remainLen -= (TLV_HEADER_LENGTH + *length);
143 }
144 /* No matched TLV found */
145 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05020, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
146 "Find TLV error: no want type(0x%x), dataLen = %u.", wantType, dataLen, 0, 0);
147 BSL_ERR_PUSH_ERROR(BSL_TLV_ERR_NO_WANT_TYPE);
148 return BSL_TLV_ERR_NO_WANT_TYPE;
149 }
150 #endif /* HITLS_BSL_TLV */
151