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 #include "securec.h"
18 #include "bsl_sal.h"
19 #include "tls_binlog_id.h"
20 #include "bsl_log_internal.h"
21 #include "bsl_log.h"
22 #include "bsl_err_internal.h"
23 #include "hitls_error.h"
24 #include "tls.h"
25 #include "rec.h"
26 #ifdef HITLS_TLS_FEATURE_FLIGHT
27 #include "bsl_uio.h"
28 #include "hitls.h"
29 #endif
30 #include "record.h"
31 #include "alert.h"
32
33 #define ALERT_DATA_LEN 2u /* alert data length */
34
35 /** Alert context, which records the sending and receiving information */
36 struct AlertCtx {
37 uint8_t flag; /* send and receive flags, for details, see ALERT_FLAG */
38 bool isFlush; /* whether the message is sent successfully */
39 uint8_t warnCount; /* count the number of consecutive received warnings */
40 uint8_t level; /* Alert level. For details, see ALERT_Level */
41 uint8_t description; /* Alert description: For details, see ALERT_Description */
42 uint8_t reverse; /* reserve, 4-byte aligned */
43 };
44
ALERT_GetFlag(const TLS_Ctx * ctx)45 bool ALERT_GetFlag(const TLS_Ctx *ctx)
46 {
47 return (ctx->alertCtx->flag != ALERT_FLAG_NO);
48 }
49
ALERT_GetInfo(const TLS_Ctx * ctx,ALERT_Info * info)50 void ALERT_GetInfo(const TLS_Ctx *ctx, ALERT_Info *info)
51 {
52 struct AlertCtx *alertCtx = ctx->alertCtx;
53 info->flag = alertCtx->flag;
54 info->level = alertCtx->level;
55 info->description = alertCtx->description;
56 return;
57 }
58
ALERT_CleanInfo(const TLS_Ctx * ctx)59 void ALERT_CleanInfo(const TLS_Ctx *ctx)
60 {
61 uint8_t alertCount = ctx->alertCtx->warnCount;
62 (void)memset_s(ctx->alertCtx, sizeof(struct AlertCtx), 0, sizeof(struct AlertCtx));
63 ctx->alertCtx->warnCount = alertCount;
64 return;
65 }
66
67 /* check whether the operation is abnormal */
AlertIsAbnormalInput(const struct AlertCtx * alertCtx,ALERT_Level level)68 bool AlertIsAbnormalInput(const struct AlertCtx *alertCtx, ALERT_Level level)
69 {
70 if (level != ALERT_LEVEL_FATAL && level != ALERT_LEVEL_WARNING) {
71 return true;
72 }
73 if (alertCtx->flag != ALERT_FLAG_NO) {
74 // a critical alert exists and cannot be overwritten
75 if (alertCtx->level == ALERT_LEVEL_FATAL) {
76 return true;
77 }
78 // common alarms are not allowed to overwrite CLOSE NOTIFY
79 if (level == ALERT_LEVEL_WARNING &&
80 alertCtx->level == ALERT_LEVEL_WARNING &&
81 alertCtx->description == ALERT_CLOSE_NOTIFY) {
82 return true;
83 }
84 }
85 return false;
86 }
87
ALERT_Send(const TLS_Ctx * ctx,ALERT_Level level,ALERT_Description description)88 void ALERT_Send(const TLS_Ctx *ctx, ALERT_Level level, ALERT_Description description)
89 {
90 struct AlertCtx *alertCtx = ctx->alertCtx;
91 // prevent abnormal operations
92 if (AlertIsAbnormalInput(alertCtx, level)) {
93 return;
94 }
95 alertCtx->level = (uint8_t)level;
96 alertCtx->description = (uint8_t)description;
97 alertCtx->flag = ALERT_FLAG_SEND;
98 alertCtx->isFlush = false;
99 return;
100 }
101
ALERT_Flush(TLS_Ctx * ctx)102 int32_t ALERT_Flush(TLS_Ctx *ctx)
103 {
104 struct AlertCtx *alertCtx = ctx->alertCtx;
105 int32_t ret;
106 if (alertCtx->flag != ALERT_FLAG_SEND) {
107 BSL_ERR_PUSH_ERROR(HITLS_ALERT_NO_WANT_SEND);
108 return HITLS_ALERT_NO_WANT_SEND;
109 }
110 if (alertCtx->isFlush == false) {
111 if (ctx->recCtx != NULL && ctx->recCtx->pendingData != NULL && alertCtx->description == ALERT_CLOSE_NOTIFY) {
112 return HITLS_REC_NORMAL_IO_BUSY;
113 }
114 uint8_t data[ALERT_DATA_LEN];
115 /** obtain the alert level */
116 data[0] = alertCtx->level;
117 data[1] = alertCtx->description;
118 if (ctx->negotiatedInfo.version == HITLS_VERSION_SSL30 && alertCtx->description == ALERT_PROTOCOL_VERSION) {
119 data[1] = ALERT_HANDSHAKE_FAILURE;
120 }
121 /** write the record */
122 ret = REC_Write(ctx, REC_TYPE_ALERT, data, ALERT_DATA_LEN);
123 if (ret != HITLS_SUCCESS) {
124 return RETURN_ERROR_NUMBER_PROCESS(ret, BINLOG_ID16267, "Write fail");
125 }
126 alertCtx->isFlush = true;
127 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15768, BSL_LOG_LEVEL_WARN, BSL_LOG_BINLOG_TYPE_RUN,
128 "Sent an Alert msg:level[%u] description[%u]", data[0], data[1], 0, 0);
129 }
130 #ifdef HITLS_TLS_FEATURE_FLIGHT
131 /* if isFlightTransmitEnable is enabled, the stored handshake information needs to be sent */
132 uint8_t isFlightTransmitEnable = 0;
133 (void)HITLS_GetFlightTransmitSwitch(ctx, &isFlightTransmitEnable);
134 if (isFlightTransmitEnable == 1) {
135 ret = BSL_UIO_Ctrl(ctx->uio, BSL_UIO_FLUSH, 0, NULL);
136 if (ret == BSL_UIO_IO_BUSY) {
137 BSL_ERR_PUSH_ERROR(HITLS_REC_NORMAL_IO_BUSY);
138 return HITLS_REC_NORMAL_IO_BUSY;
139 }
140 if (ret != BSL_SUCCESS) {
141 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16111, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
142 "fail to send alert message in bUio.", 0, 0, 0, 0);
143 BSL_ERR_PUSH_ERROR(HITLS_REC_ERR_IO_EXCEPTION);
144 return HITLS_REC_ERR_IO_EXCEPTION;
145 }
146 }
147 #endif /* HITLS_TLS_FEATURE_FLIGHT */
148 return HITLS_SUCCESS;
149 }
150
151 #ifdef HITLS_TLS_PROTO_TLS13
ALERT_GetVersion(const TLS_Ctx * ctx)152 static uint32_t ALERT_GetVersion(const TLS_Ctx *ctx)
153 {
154 if (ctx->negotiatedInfo.version > 0) {
155 /* the version has been negotiated */
156 return ctx->negotiatedInfo.version;
157 } else {
158 /* if the version is not negotiated, the latest version supported by the local end is returned */
159 return ctx->config.tlsConfig.maxVersion;
160 }
161 }
162 #endif /* HITLS_TLS_PROTO_TLS13 */
163
ALERT_Init(TLS_Ctx * ctx)164 int32_t ALERT_Init(TLS_Ctx *ctx)
165 {
166 if (ctx == NULL) {
167 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15772, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, "ctx null.", 0, 0, 0, 0);
168 BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT);
169 return HITLS_NULL_INPUT;
170 }
171 // prevent multi init of ctx->alertCtx
172 if (ctx->alertCtx != NULL) {
173 return HITLS_SUCCESS;
174 }
175 ctx->alertCtx = (struct AlertCtx *)BSL_SAL_Malloc(sizeof(struct AlertCtx));
176 if (ctx->alertCtx == NULL) {
177 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15773, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
178 "malloc alert ctx fail.", 0, 0, 0, 0);
179 BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL);
180 return HITLS_MEMALLOC_FAIL;
181 }
182 (void)memset_s(ctx->alertCtx, sizeof(struct AlertCtx), 0, sizeof(struct AlertCtx));
183 return HITLS_SUCCESS;
184 }
185
ALERT_Deinit(TLS_Ctx * ctx)186 void ALERT_Deinit(TLS_Ctx *ctx)
187 {
188 if (ctx == NULL) {
189 return;
190 }
191 BSL_SAL_FREE(ctx->alertCtx);
192 return;
193 }
194
ProcessDecryptedAlert(TLS_Ctx * ctx,const uint8_t * data,uint32_t dataLen)195 int32_t ProcessDecryptedAlert(TLS_Ctx *ctx, const uint8_t *data, uint32_t dataLen)
196 {
197 struct AlertCtx *alertCtx = ctx->alertCtx;
198
199 /** if the message lengths are not equal, an error code is returned */
200 if (dataLen != ALERT_DATA_LEN) {
201 BSL_ERR_PUSH_ERROR(HITLS_REC_NORMAL_RECV_UNEXPECT_MSG);
202 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15769, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
203 "get a alert msg with illegal len %u", dataLen, 0, 0, 0);
204 ALERT_Send(ctx, ALERT_LEVEL_FATAL, ALERT_UNEXPECTED_MESSAGE);
205 return HITLS_REC_NORMAL_RECV_UNEXPECT_MSG;
206 }
207
208 /** record the alert message */
209 if (data[0] == ALERT_LEVEL_FATAL || data[0] == ALERT_LEVEL_WARNING) {
210 // prevent abnormal operations
211 if (AlertIsAbnormalInput(alertCtx, data[0]) == true) {
212 return RETURN_ERROR_NUMBER_PROCESS(HITLS_REC_NORMAL_RECV_UNEXPECT_MSG, BINLOG_ID16268, "input abnormal");
213 }
214 alertCtx->flag = ALERT_FLAG_RECV;
215 alertCtx->level = data[0];
216 alertCtx->description = data[1];
217 #ifdef HITLS_TLS_PROTO_TLS13
218 if (ALERT_GetVersion(ctx) == HITLS_VERSION_TLS13 && alertCtx->description != ALERT_CLOSE_NOTIFY) {
219 alertCtx->level = ALERT_LEVEL_FATAL;
220 }
221 #endif
222 if (alertCtx->level == ALERT_LEVEL_FATAL) {
223 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16269, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
224 "alert fatal", 0, 0, 0, 0);
225 BSL_ERR_PUSH_ERROR(HITLS_REC_NORMAL_RECV_UNEXPECT_MSG);
226 }
227 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15770, BSL_LOG_LEVEL_WARN, BSL_LOG_BINLOG_TYPE_RUN,
228 "got a alert msg:level[%u] description[%u]", data[0], data[1], 0, 0);
229 return HITLS_REC_NORMAL_RECV_UNEXPECT_MSG;
230 }
231
232 BSL_ERR_PUSH_ERROR(HITLS_REC_NORMAL_RECV_UNEXPECT_MSG);
233 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15771, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
234 "get a alert msg with illegal type", 0, 0, 0, 0);
235 /** Decoding error. Send an alert. */
236 ALERT_Send(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER);
237 return HITLS_REC_NORMAL_RECV_UNEXPECT_MSG;
238 }
239 #ifdef HITLS_TLS_PROTO_TLS13
ProcessPlainAlert(TLS_Ctx * ctx,const uint8_t * data,uint32_t dataLen)240 int32_t ProcessPlainAlert(TLS_Ctx *ctx, const uint8_t *data, uint32_t dataLen)
241 {
242 if (ctx->isClient == true && REC_HaveReadSuiteInfo(ctx)) {
243 return RETURN_ALERT_PROCESS(ctx, HITLS_REC_NORMAL_RECV_UNEXPECT_MSG, BINLOG_ID16270,
244 "receive plain alert", ALERT_UNEXPECTED_MESSAGE);
245 }
246 if (ctx->isClient == false && ctx->plainAlertForbid == true) {
247 return RETURN_ALERT_PROCESS(ctx, HITLS_REC_NORMAL_RECV_UNEXPECT_MSG, BINLOG_ID16271,
248 "tls1.3 forbid to receive plain alert", ALERT_UNEXPECTED_MESSAGE);
249 }
250 return ProcessDecryptedAlert(ctx, data, dataLen);
251 }
252 #endif /* HITLS_TLS_PROTO_TLS13 */
ALERT_ClearWarnCount(TLS_Ctx * ctx)253 void ALERT_ClearWarnCount(TLS_Ctx *ctx)
254 {
255 ctx->alertCtx->warnCount = 0;
256 return;
257 }
258
ALERT_HaveExceeded(TLS_Ctx * ctx,uint8_t threshold)259 bool ALERT_HaveExceeded(TLS_Ctx *ctx, uint8_t threshold)
260 {
261 ctx->alertCtx->warnCount += 1;
262 return ctx->alertCtx->warnCount >= threshold;
263 }
264
265 #ifdef HITLS_BSL_LOG
ReturnAlertProcess(TLS_Ctx * ctx,int32_t err,uint32_t logId,const void * logStr,ALERT_Description description)266 int32_t ReturnAlertProcess(TLS_Ctx *ctx, int32_t err, uint32_t logId, const void *logStr,
267 ALERT_Description description)
268 {
269 if (logStr != NULL) {
270 BSL_LOG_BINLOG_FIXLEN(logId, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, logStr, 0, 0, 0, 0);
271 }
272 if (description != ALERT_UNKNOWN) {
273 ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, description);
274 }
275 return err;
276 }
277
ReturnErrorNumberProcess(int32_t err,uint32_t logId,const void * logStr)278 int32_t ReturnErrorNumberProcess(int32_t err, uint32_t logId, const void *logStr)
279 {
280 (void)logStr;
281 BSL_LOG_BINLOG_FIXLEN(logId, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, logStr, 0, 0, 0, 0);
282 return err;
283 }
284 #endif /* HITLS_BSL_LOG */