• 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_UIO_SCTP
18 
19 #include "securec.h"
20 #include "bsl_sal.h"
21 #include "bsl_binlog_id.h"
22 #include "bsl_log_internal.h"
23 #include "bsl_log.h"
24 #include "bsl_err_internal.h"
25 #include "bsl_errno.h"
26 #include "bsl_uio.h"
27 #include "sal_net.h"
28 #include "uio_base.h"
29 #include "uio_abstraction.h"
30 
31 #define SCTP_SHARE_AUTHKEY_ID_MAX 65535
32 
33 typedef struct {
34     bool peerAuthed;                /* Whether auth is enabled at the peer end */
35     /* Whether authkey is added: If authkey is added but not active, success is returned when authkey is added again. */
36     bool isAddAuthkey;
37     bool reserved[2];                /* Four-byte alignment is reserved. */
38 
39     uint16_t sendAppStreamId;       /* ID of the stream sent by the user-specified app. */
40     uint16_t prevShareKeyId;
41     uint16_t shareKeyId;
42     uint16_t reserved1;              /* Four-byte alignment is reserved. */
43 } BslSctpData;
44 
45 typedef struct {
46     BslSctpData data;
47     int32_t fd;                 // Network socket
48     uint32_t ipLen;
49     uint8_t ip[IP_ADDR_MAX_LEN];
50     struct BSL_UIO_MethodStruct method;
51     bool isAppMsg;              // whether the message sent is the app message
52 } SctpParameters;
53 
BslSctpNew(BSL_UIO * uio)54 static int32_t BslSctpNew(BSL_UIO *uio)
55 {
56     SctpParameters *parameters = (SctpParameters *)BSL_SAL_Calloc(1u, sizeof(SctpParameters));
57     if (parameters == NULL) {
58         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05031, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
59             "Uio: sctp param malloc fail.", 0, 0, 0, 0);
60         BSL_ERR_PUSH_ERROR(BSL_UIO_FAIL);
61         return BSL_UIO_FAIL;
62     }
63     parameters->fd = -1;
64     parameters->method.uioType = BSL_UIO_SCTP;
65     uio->ctx = parameters;
66     uio->ctxLen = sizeof(SctpParameters);
67     // The default value of init is 0. Set the value of init to 1 after the fd is set.
68     return BSL_SUCCESS;
69 }
70 
BslSctpDestroy(BSL_UIO * uio)71 static int32_t BslSctpDestroy(BSL_UIO *uio)
72 {
73     if (uio == NULL) {
74         return BSL_SUCCESS;
75     }
76     SctpParameters *ctx = BSL_UIO_GetCtx(uio);
77     uio->init = 0;
78     if (ctx != NULL) {
79         if (BSL_UIO_GetIsUnderlyingClosedByUio(uio) && ctx->fd != -1) {
80             (void)BSL_SAL_SockClose(ctx->fd);
81         }
82         BSL_SAL_FREE(ctx);
83         BSL_UIO_SetCtx(uio, NULL);
84     }
85     return BSL_SUCCESS;
86 }
87 
BslSctpWrite(BSL_UIO * uio,const void * buf,uint32_t len,uint32_t * writeLen)88 static int32_t BslSctpWrite(BSL_UIO *uio, const void *buf, uint32_t len, uint32_t *writeLen)
89 {
90     if (uio == NULL || uio->ctx == NULL || ((SctpParameters *)uio->ctx)->method.uioWrite == NULL) {
91         BSL_ERR_PUSH_ERROR(BSL_INVALID_ARG);
92         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05081, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
93             "Uio: Sctp write input error.", 0, 0, 0, 0);
94         return BSL_INVALID_ARG;
95     }
96     *writeLen = 0;
97     return ((SctpParameters *)uio->ctx)->method.uioWrite(uio, buf, len, writeLen);
98 }
99 
BslSctpRead(BSL_UIO * uio,void * buf,uint32_t len,uint32_t * readLen)100 static int32_t BslSctpRead(BSL_UIO *uio, void *buf, uint32_t len, uint32_t *readLen)
101 {
102     if (uio == NULL || uio->ctx == NULL || ((SctpParameters *)uio->ctx)->method.uioRead == NULL) {
103         BSL_ERR_PUSH_ERROR(BSL_INVALID_ARG);
104         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05082, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
105             "Uio: Sctp read input error.", 0, 0, 0, 0);
106         return BSL_INVALID_ARG;
107     }
108     *readLen = 0;
109     SctpParameters *parameters = (SctpParameters *)uio->ctx;
110     if (!parameters->data.peerAuthed) {
111         if (parameters->method.uioCtrl == NULL || parameters->method.uioCtrl(uio, BSL_UIO_SCTP_CHECK_PEER_AUTH,
112             sizeof(parameters->data.peerAuthed), &parameters->data.peerAuthed) != BSL_SUCCESS) {
113             BSL_ERR_PUSH_ERROR(BSL_UIO_IO_EXCEPTION);
114             BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05083, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
115                 "Uio: Check peer auth failed.", 0, 0, 0, 0);
116             return BSL_UIO_IO_EXCEPTION;
117         }
118         parameters->data.peerAuthed = true;
119     }
120     return parameters->method.uioRead(uio, buf, len, readLen);
121 }
122 
BslSctpAddAuthKey(BSL_UIO * uio,const uint8_t * parg,uint16_t larg)123 static int32_t BslSctpAddAuthKey(BSL_UIO *uio, const uint8_t *parg, uint16_t larg)
124 {
125     SctpParameters *parameters = (SctpParameters *)BSL_UIO_GetCtx(uio);
126     if (parg == NULL || larg != sizeof(BSL_UIO_SctpAuthKey)) {
127         BSL_ERR_PUSH_ERROR(BSL_INVALID_ARG);
128         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05062, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
129             "add auth key failed", 0, 0, 0, 0);
130         return BSL_INVALID_ARG;
131     }
132 
133     if (parameters->data.isAddAuthkey) {
134         return BSL_SUCCESS;
135     }
136 
137     uint16_t prevShareKeyId = parameters->data.shareKeyId;
138     if (parameters->data.shareKeyId >= SCTP_SHARE_AUTHKEY_ID_MAX) {
139         parameters->data.shareKeyId = 1;
140     } else {
141         parameters->data.shareKeyId++;
142     }
143     BSL_UIO_SctpAuthKey key = { 0 };
144     key.shareKeyId = parameters->data.shareKeyId;
145     key.authKey = parg;
146     key.authKeySize = larg;
147 
148     int32_t ret = parameters->method.uioCtrl(uio, BSL_UIO_SCTP_ADD_AUTH_SHARED_KEY, (int32_t)sizeof(key), &key);
149     if (ret != BSL_SUCCESS) {
150         parameters->data.shareKeyId = prevShareKeyId;
151         BSL_ERR_PUSH_ERROR(BSL_UIO_IO_EXCEPTION);
152         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05065, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
153             "add auth key failed", 0, 0, 0, 0);
154         return BSL_UIO_IO_EXCEPTION;
155     }
156     parameters->data.isAddAuthkey = true;
157     parameters->data.prevShareKeyId = prevShareKeyId;
158     return BSL_SUCCESS;
159 }
160 
BslSctpActiveAuthKey(BSL_UIO * uio)161 static int32_t BslSctpActiveAuthKey(BSL_UIO *uio)
162 {
163     SctpParameters *parameters = BSL_UIO_GetCtx(uio);
164     if (parameters == NULL || parameters->method.uioCtrl == NULL) {
165         BSL_ERR_PUSH_ERROR(BSL_NULL_INPUT);
166         return BSL_NULL_INPUT;
167     }
168     uint16_t shareKeyId = parameters->data.shareKeyId;
169     int32_t ret = parameters->method.uioCtrl(uio, BSL_UIO_SCTP_ACTIVE_AUTH_SHARED_KEY,
170         (int32_t)sizeof(shareKeyId), &shareKeyId);
171     if (ret != BSL_SUCCESS) {
172         BSL_ERR_PUSH_ERROR(BSL_UIO_IO_EXCEPTION);
173         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05066, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
174             "active auth key failed", 0, 0, 0, 0);
175         return BSL_UIO_IO_EXCEPTION;
176     }
177     parameters->data.isAddAuthkey = false;
178     return BSL_SUCCESS;
179 }
180 
BslSctpDelPreAuthKey(BSL_UIO * uio)181 static int32_t BslSctpDelPreAuthKey(BSL_UIO *uio)
182 {
183     SctpParameters *parameters = BSL_UIO_GetCtx(uio);
184     if (parameters == NULL || parameters->method.uioCtrl == NULL) {
185         BSL_ERR_PUSH_ERROR(BSL_NULL_INPUT);
186         return BSL_NULL_INPUT;
187     }
188     uint16_t delShareKeyId = parameters->data.prevShareKeyId;
189     int32_t ret = parameters->method.uioCtrl(uio, BSL_UIO_SCTP_DEL_PRE_AUTH_SHARED_KEY,
190         (int32_t)sizeof(delShareKeyId), &delShareKeyId);
191     if (ret != BSL_SUCCESS) {
192         BSL_ERR_PUSH_ERROR(BSL_UIO_IO_EXCEPTION);
193         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05067, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
194             "del pre auth key failed", 0, 0, 0, 0);
195         return BSL_UIO_IO_EXCEPTION;
196     }
197     return BSL_SUCCESS;
198 }
199 
BslSctpIsSndBuffEmpty(BSL_UIO * uio,void * parg,int32_t larg)200 static int32_t BslSctpIsSndBuffEmpty(BSL_UIO *uio, void *parg, int32_t larg)
201 {
202     SctpParameters *parameters = BSL_UIO_GetCtx(uio);
203     if (parameters == NULL || parameters->method.uioCtrl == NULL || parg == NULL || larg != sizeof(bool)) {
204         BSL_ERR_PUSH_ERROR(BSL_NULL_INPUT);
205         return BSL_NULL_INPUT;
206     }
207     uint8_t isEmpty = 0;
208     if (parameters->method.uioCtrl(uio, BSL_UIO_SCTP_SND_BUFF_IS_EMPTY,
209         (int32_t)sizeof(uint8_t), &isEmpty) != BSL_SUCCESS) {
210         BSL_ERR_PUSH_ERROR(BSL_UIO_IO_EXCEPTION);
211         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05068, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
212             "get sctp status failed", 0, 0, 0, 0);
213         return BSL_UIO_IO_EXCEPTION;
214     }
215     *(bool *)parg = (isEmpty > 0);
216     return BSL_SUCCESS;
217 }
218 
BslSctpGetSendStreamId(const SctpParameters * parameters,void * parg,int32_t larg)219 static int32_t BslSctpGetSendStreamId(const SctpParameters *parameters, void *parg, int32_t larg)
220 {
221     if (larg != (int32_t)sizeof(uint16_t) || parg == NULL) {
222         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05046, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
223             "Uio: Sctp input err.", 0, 0, 0, 0);
224         BSL_ERR_PUSH_ERROR(BSL_NULL_INPUT);
225         return BSL_NULL_INPUT;
226     }
227     uint16_t *sendStreamId = (uint16_t *)parg;
228     if (parameters->isAppMsg) {
229         *sendStreamId = parameters->data.sendAppStreamId;
230     } else {
231         *sendStreamId = 0;
232     }
233 
234     BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05047, BSL_LOG_LEVEL_DEBUG, BSL_LOG_BINLOG_TYPE_RUN,
235         "Uio: User Get SCTP send StreamId [%hu].", *sendStreamId, 0, 0, 0);
236     return BSL_SUCCESS;
237 }
238 
BslSctpSetAppStreamId(SctpParameters * parameters,const void * parg,int32_t larg)239 int32_t BslSctpSetAppStreamId(SctpParameters *parameters, const void *parg, int32_t larg)
240 {
241     if (larg != (int32_t)sizeof(uint16_t) || parg == NULL) {
242         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05048, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
243             "Uio: Sctp input err.", 0, 0, 0, 0);
244         BSL_ERR_PUSH_ERROR(BSL_NULL_INPUT);
245         return BSL_NULL_INPUT;
246     }
247     parameters->data.sendAppStreamId = *(const uint16_t *)parg;
248     BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05055, BSL_LOG_LEVEL_DEBUG, BSL_LOG_BINLOG_TYPE_RUN,
249         "Uio: User set SCTP AppStreamId [%hu].", parameters->data.sendAppStreamId, 0, 0, 0);
250     return BSL_SUCCESS;
251 }
252 
BslSctpSetPeerIpAddr(SctpParameters * parameters,const uint8_t * addr,int32_t size)253 static int32_t BslSctpSetPeerIpAddr(SctpParameters *parameters, const uint8_t *addr, int32_t size)
254 {
255     if (addr == NULL) {
256         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05049, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
257             "Uio: NULL error.", 0, 0, 0, 0);
258         BSL_ERR_PUSH_ERROR(BSL_NULL_INPUT);
259         return BSL_NULL_INPUT;
260     }
261 
262     if (size != IP_ADDR_V4_LEN && size != IP_ADDR_V6_LEN) {
263         BSL_ERR_PUSH_ERROR(BSL_UIO_FAIL);
264         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05050, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
265             "Uio: Set peer ip address input error.", 0, 0, 0, 0);
266         return BSL_UIO_FAIL;
267     }
268 
269     (void)memcpy_s(parameters->ip, sizeof(parameters->ip), addr, size);
270     parameters->ipLen = (uint32_t)size;
271     return BSL_SUCCESS;
272 }
273 
BslSctpGetPeerIpAddr(SctpParameters * parameters,void * parg,int32_t larg)274 static int32_t BslSctpGetPeerIpAddr(SctpParameters *parameters, void *parg, int32_t larg)
275 {
276     BSL_UIO_CtrlGetPeerIpAddrParam *para = (BSL_UIO_CtrlGetPeerIpAddrParam *)parg;
277     if (parg == NULL || larg != (int32_t)sizeof(BSL_UIO_CtrlGetPeerIpAddrParam) ||
278         para->addr == NULL) {
279         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05051, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
280             "Uio: Get peer ip address input error.", 0, 0, 0, 0);
281         return BSL_NULL_INPUT;
282     }
283 
284     /* Check whether the IP address is set. */
285     if (parameters->ipLen == 0) {
286         BSL_ERR_PUSH_ERROR(BSL_UIO_FAIL);
287         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05052, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
288             "Uio: Ip address is already existed.", 0, 0, 0, 0);
289         return BSL_UIO_FAIL;
290     }
291 
292     if (para->size < parameters->ipLen) {
293         BSL_ERR_PUSH_ERROR(BSL_UIO_FAIL);
294         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05053, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
295             "Uio: Ip address length err.", 0, 0, 0, 0);
296         return BSL_UIO_FAIL;
297     }
298 
299     (void)memcpy_s(para->addr, para->size, parameters->ip, parameters->ipLen);
300     para->size = parameters->ipLen;
301     return BSL_SUCCESS;
302 }
303 
BslSctpSetFd(BSL_UIO * uio,void * parg,int32_t larg)304 static int32_t BslSctpSetFd(BSL_UIO *uio, void *parg, int32_t larg)
305 {
306     if (larg != (int32_t)sizeof(int32_t) || parg == NULL) {
307         BSL_ERR_PUSH_ERROR(BSL_INVALID_ARG);
308         return BSL_INVALID_ARG;
309     }
310     int32_t *fd = (int32_t *)parg;
311     SctpParameters *parameters = BSL_UIO_GetCtx(uio);
312     if (parameters->fd != -1) {
313         if (BSL_UIO_GetIsUnderlyingClosedByUio(uio)) {
314             (void)BSL_SAL_SockClose(parameters->fd);
315         }
316     }
317     parameters->fd = *fd;
318     uio->init = true;
319     return BSL_SUCCESS;
320 }
321 
BslSctpGetFd(SctpParameters * parameters,void * parg,int32_t larg)322 static int32_t BslSctpGetFd(SctpParameters *parameters, void *parg, int32_t larg)
323 {
324     if (larg != (int32_t)sizeof(int32_t) || parg == NULL) {
325         BSL_ERR_PUSH_ERROR(BSL_INVALID_ARG);
326         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05054, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
327             "get fd handle invalid parameter.", 0, 0, 0, 0);
328         return BSL_INVALID_ARG;
329     }
330     *(int32_t *)parg = parameters->fd;
331     return BSL_SUCCESS;
332 }
333 
BslSctpMaskAppMsg(SctpParameters * parameters,void * parg,int32_t larg)334 static int32_t BslSctpMaskAppMsg(SctpParameters *parameters, void *parg, int32_t larg)
335 {
336     if (parg == NULL || larg != sizeof(bool)) {
337         BSL_ERR_PUSH_ERROR(BSL_INVALID_ARG);
338         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05030, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
339             "mask app msg failed", 0, 0, 0, 0);
340         return BSL_INVALID_ARG;
341     }
342     parameters->isAppMsg = *(bool *)parg;
343     return BSL_SUCCESS;
344 }
345 
BslSctpSetCtxCb(SctpParameters * parameters,int32_t type,void * func)346 static int32_t BslSctpSetCtxCb(SctpParameters *parameters, int32_t type, void *func)
347 {
348     if (parameters == NULL || func == NULL) {
349         BSL_ERR_PUSH_ERROR(BSL_NULL_INPUT);
350         return BSL_NULL_INPUT;
351     }
352     switch (type) {
353         case BSL_UIO_WRITE_CB:
354             parameters->method.uioWrite = func;
355             break;
356         case BSL_UIO_READ_CB:
357             parameters->method.uioRead = func;
358             break;
359         case BSL_UIO_CTRL_CB:
360             parameters->method.uioCtrl = func;
361             break;
362         default:
363             BSL_ERR_PUSH_ERROR(BSL_INVALID_ARG);
364             return BSL_INVALID_ARG;
365     }
366     return BSL_SUCCESS;
367 }
368 
BslSctpCtrl(BSL_UIO * uio,int32_t cmd,int32_t larg,void * parg)369 int32_t BslSctpCtrl(BSL_UIO *uio, int32_t cmd, int32_t larg, void *parg)
370 {
371     if (uio->ctx == NULL) {
372         return BSL_NULL_INPUT;
373     }
374     SctpParameters *parameters = BSL_UIO_GetCtx(uio);
375     switch (cmd) {
376         case BSL_UIO_SET_PEER_IP_ADDR:
377             return BslSctpSetPeerIpAddr(parameters, parg, larg);
378         case BSL_UIO_GET_PEER_IP_ADDR:
379             return BslSctpGetPeerIpAddr(parameters, parg, larg);
380         case BSL_UIO_SET_FD:
381             return BslSctpSetFd(uio, parg, larg);
382         case BSL_UIO_GET_FD:
383             return BslSctpGetFd(parameters, parg, larg);
384         case BSL_UIO_SCTP_GET_SEND_STREAM_ID:
385             return BslSctpGetSendStreamId(parameters, parg, larg);
386         case BSL_UIO_SCTP_SET_APP_STREAM_ID:
387             return BslSctpSetAppStreamId(parameters, parg, larg);
388         case BSL_UIO_SCTP_ADD_AUTH_SHARED_KEY:
389             if (larg < 0 || larg > UINT16_MAX) {
390                 break;
391             }
392             return BslSctpAddAuthKey(uio, parg, larg);
393         case BSL_UIO_SCTP_ACTIVE_AUTH_SHARED_KEY:
394             return BslSctpActiveAuthKey(uio);
395         case BSL_UIO_SCTP_DEL_PRE_AUTH_SHARED_KEY:
396             return BslSctpDelPreAuthKey(uio);
397         case BSL_UIO_SCTP_MASK_APP_MESSAGE:
398             return BslSctpMaskAppMsg(parameters, parg, larg);
399         case BSL_UIO_SCTP_SND_BUFF_IS_EMPTY:
400             return BslSctpIsSndBuffEmpty(uio, parg, larg);
401         case BSL_UIO_SCTP_SET_CALLBACK:
402             return BslSctpSetCtxCb(parameters, larg, parg);
403         case BSL_UIO_FLUSH:
404             return BSL_SUCCESS;
405         default:
406             break;
407     }
408     BSL_ERR_PUSH_ERROR(BSL_INVALID_ARG);
409     BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05069, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
410         "invalid args", 0, 0, 0, 0);
411     return BSL_INVALID_ARG;
412 }
413 
BSL_UIO_SctpMethod(void)414 const BSL_UIO_Method *BSL_UIO_SctpMethod(void)
415 {
416     static const BSL_UIO_Method method = {
417         BSL_UIO_SCTP,
418         BslSctpWrite,
419         BslSctpRead,
420         BslSctpCtrl,
421         NULL,
422         NULL,
423         BslSctpNew,
424         BslSctpDestroy
425     };
426     return &method;
427 }
428 #endif /* HITLS_BSL_UIO_SCTP */
429