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 #include "hitls_build.h"
16 #include "securec.h"
17 #include "bsl_sal.h"
18 #include "bsl_list.h"
19 #include "tls_binlog_id.h"
20 #include "bsl_uio.h"
21 #include "bsl_log_internal.h"
22 #include "bsl_log.h"
23 #include "bsl_err_internal.h"
24 #include "hitls_error.h"
25 #include "rec.h"
26 #include "app_ctx.h"
27 #include "rec.h"
28 #include "record.h"
29 #include "app.h"
30
ReadAppData(TLS_Ctx * ctx,uint8_t * buf,uint32_t num,uint32_t * readLen)31 static int32_t ReadAppData(TLS_Ctx *ctx, uint8_t *buf, uint32_t num, uint32_t *readLen)
32 {
33 return REC_Read(ctx, REC_TYPE_APP, buf, readLen, num);
34 }
35
APP_Read(TLS_Ctx * ctx,uint8_t * buf,uint32_t num,uint32_t * readLen)36 int32_t APP_Read(TLS_Ctx *ctx, uint8_t *buf, uint32_t num, uint32_t *readLen)
37 {
38 int32_t ret;
39 uint32_t readbytes;
40
41 if (ctx == NULL || buf == NULL || num == 0) {
42 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15659, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
43 "APP: input null pointer or read bufLen is 0.", 0, 0, 0, 0);
44 BSL_ERR_PUSH_ERROR(HITLS_APP_ERR_ZERO_READ_BUF_LEN);
45 return HITLS_APP_ERR_ZERO_READ_BUF_LEN;
46 }
47 // read data to the buffer in non-blocking mode
48 do {
49 ret = ReadAppData(ctx, buf, num, &readbytes);
50 if (ret != HITLS_SUCCESS) {
51 return ret;
52 }
53 } while (readbytes == 0); // do not exit the loop until data is read
54
55 *readLen = readbytes;
56 return HITLS_SUCCESS;
57 }
58
APP_GetMaxWriteSize(const TLS_Ctx * ctx,uint32_t * len)59 int32_t APP_GetMaxWriteSize(const TLS_Ctx *ctx, uint32_t *len)
60 {
61 return REC_GetMaxWriteSize(ctx, len);
62 }
63
SavePendingData(TLS_Ctx * ctx,const uint8_t * data,uint32_t dataLen)64 static int32_t SavePendingData(TLS_Ctx *ctx, const uint8_t *data, uint32_t dataLen)
65 {
66 #ifdef HITLS_TLS_PROTO_DTLS
67 if (IS_SUPPORT_DATAGRAM(ctx->config.tlsConfig.originVersionMask)) {
68 return HITLS_SUCCESS;
69 }
70 #endif
71 RecCtx *recCtx = (RecCtx *)ctx->recCtx;
72 if (recCtx->pendingData != NULL) {
73 if (recCtx->pendingData != data || recCtx->pendingDataSize != dataLen) {
74 ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR);
75 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16241, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
76 "The two buffer addresses are inconsistent.", 0, 0, 0, 0);
77 return HITLS_APP_ERR_WRITE_BAD_RETRY;
78 }
79 }
80 // Stores the plaintext data to be sent.
81 recCtx->pendingData = data;
82 recCtx->pendingDataSize = dataLen;
83 return HITLS_SUCCESS;
84 }
85
CheckDataLen(TLS_Ctx * ctx,const uint8_t * data,uint32_t * sendLen)86 static int32_t CheckDataLen(TLS_Ctx *ctx, const uint8_t *data, uint32_t *sendLen)
87 {
88 uint32_t maxWriteLen = 0u;
89 int32_t ret = REC_GetMaxWriteSize(ctx, &maxWriteLen);
90 if (ret != HITLS_SUCCESS) {
91 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15660, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
92 "APP: Get record max write size fail.", 0, 0, 0, 0);
93 return ret;
94 }
95 if (*sendLen > maxWriteLen) {
96 *sendLen = maxWriteLen;
97 }
98
99 return SavePendingData(ctx, data, *sendLen);
100 }
101
APP_Write(TLS_Ctx * ctx,const uint8_t * data,uint32_t dataLen,uint32_t * writeLen)102 int32_t APP_Write(TLS_Ctx *ctx, const uint8_t *data, uint32_t dataLen, uint32_t *writeLen)
103 {
104 uint32_t sendLen = dataLen;
105 int32_t ret = CheckDataLen(ctx, data, &sendLen);
106 if (ret != HITLS_SUCCESS) {
107 return ret;
108 }
109 *writeLen = 0;
110
111 ret = REC_Write(ctx, REC_TYPE_APP, data, sendLen);
112 if (ret != HITLS_SUCCESS) {
113 return RETURN_ERROR_NUMBER_PROCESS(ret, BINLOG_ID16274, "Write fail");
114 }
115 #ifdef HITLS_TLS_FEATURE_FLIGHT
116 if (ctx->config.tlsConfig.isFlightTransmitEnable) {
117 ret = BSL_UIO_Ctrl(ctx->uio, BSL_UIO_FLUSH, 0, NULL);
118 if (ret == BSL_UIO_IO_BUSY) {
119 return HITLS_REC_NORMAL_IO_BUSY;
120 }
121 if (ret != BSL_SUCCESS) {
122 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16112, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
123 "fail to send handshake message in bUio.", 0, 0, 0, 0);
124 return HITLS_REC_ERR_IO_EXCEPTION;
125 }
126 }
127 #endif
128 *writeLen = sendLen;
129 ctx->recCtx->pendingData = NULL;
130 ctx->recCtx->pendingDataSize = 0;
131 return HITLS_SUCCESS;
132 }