• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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