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 <string.h>
16 #include "securec.h"
17 #include "hitls_build.h"
18 #include "bsl_bytes.h"
19 #include "bsl_log_internal.h"
20 #include "bsl_err_internal.h"
21 #ifdef HITLS_TLS_SUITE_CIPHER_AEAD
22 #include "rec_crypto_aead.h"
23 #endif
24 #ifdef HITLS_TLS_SUITE_CIPHER_CBC
25 #include "rec_crypto_cbc.h"
26 #endif
27 #include "tls_binlog_id.h"
28 #include "rec_conn.h"
29 #include "rec_alert.h"
30 #include "indicator.h"
31 #include "hs.h"
32 #include "hitls_error.h"
33
34 #ifdef HITLS_TLS_PROTO_TLS13
35 /* 16384 + 1: RFC8446 5.4. Record Padding the full encoded TLSInnerPlaintext MUST NOT exceed 2^14 + 1 octets. */
36 #define MAX_PADDING_LEN 16385
37
38
39 /* *
40 * @brief Obtain the content and record message types from the decrypted TLSInnerPlaintext.
41 * After TLS1.3 decryption, the TLSInnerPlaintext structure is used. The padding needs to be
42 removed and the actual message type needs to be obtained.
43 *
44 * struct {
45 * opaque content[TLSPlaintext.length];
46 * ContentType type;
47 * uint8 zeros[length_of_padding];
48 * } TLSInnerPlaintext;
49 *
50 * @param text [IN] Decrypted content (TLSInnerPlaintext)
51 * @param textLen [OUT] Input (length of TLSInnerPlaintext)
52 * Length of the output content
53 * @param recType [OUT] Message body length
54 *
55 * @return HITLS_SUCCESS succeeded
56 * HITLS_ALERT_FATAL Unexpected Message
57 */
RecParseInnerPlaintext(TLS_Ctx * ctx,const uint8_t * text,uint32_t * textLen,uint8_t * recType)58 int32_t RecParseInnerPlaintext(TLS_Ctx *ctx, const uint8_t *text, uint32_t *textLen, uint8_t *recType)
59 {
60 /* The receiver decrypts and scans the field from the end to the beginning until it finds a non-zero octet. This
61 * non-zero byte is the message type of record If no non-zero bytes are found, an unexpected alert needs to be sent
62 * and the chain is terminated
63 */
64 uint32_t len = *textLen;
65 for (uint32_t i = len; i > 0; i--) {
66 if (text[i - 1] != 0) {
67 *recType = text[i - 1];
68 // When the value is the same as the rectype index, the value is the length of the content
69 *textLen = i - 1;
70 return HITLS_SUCCESS;
71 }
72 }
73
74 BSL_ERR_PUSH_ERROR(HITLS_REC_ERR_RECV_UNEXPECTED_MSG);
75 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15453, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
76 "Recved UNEXPECTED_MESSAGE.", 0, 0, 0, 0);
77 return RecordSendAlertMsg(ctx, ALERT_LEVEL_FATAL, ALERT_UNEXPECTED_MESSAGE);
78 }
79 #endif /* HITLS_TLS_PROTO_TLS13 */
80
DefaultDecryptPostProcess(TLS_Ctx * ctx,RecConnSuitInfo * suiteInfo,REC_TextInput * encryptedMsg,uint8_t * data,uint32_t * dataLen)81 static int32_t DefaultDecryptPostProcess(TLS_Ctx *ctx, RecConnSuitInfo *suiteInfo, REC_TextInput *encryptedMsg,
82 uint8_t *data, uint32_t *dataLen)
83 {
84 (void)ctx;
85 (void)suiteInfo;
86 (void)encryptedMsg;
87 (void)data;
88 (void)dataLen;
89 #ifdef HITLS_TLS_PROTO_TLS13
90 /* If the version is tls1.3 and encryption is required, you need to create a TLSInnerPlaintext message */
91 if (ctx->negotiatedInfo.version == HITLS_VERSION_TLS13 && suiteInfo != NULL) {
92 return RecParseInnerPlaintext(ctx, data, dataLen, &encryptedMsg->type);
93 }
94 #endif
95 return HITLS_SUCCESS;
96 }
DefaultEncryptPreProcess(TLS_Ctx * ctx,uint8_t recordType,const uint8_t * data,uint32_t plainLen,RecordPlaintext * recPlaintext)97 static int32_t DefaultEncryptPreProcess(TLS_Ctx *ctx, uint8_t recordType, const uint8_t *data, uint32_t plainLen,
98 RecordPlaintext *recPlaintext)
99 {
100 #ifdef HITLS_TLS_PROTO_TLS
101 (void)ctx, (void)data;
102 recPlaintext->recordType = recordType;
103 recPlaintext->plainLen = plainLen;
104 recPlaintext->plainData = NULL;
105 #ifdef HITLS_TLS_PROTO_TLS13
106 if (ctx->negotiatedInfo.version != HITLS_VERSION_TLS13 ||
107 ctx->recCtx->writeStates.currentState->suiteInfo == NULL) {
108 return HITLS_SUCCESS;
109 }
110 recPlaintext->isTlsInnerPlaintext = true;
111 /* Currently, the padding length is set to 0. If required, the padding length can be customized */
112 uint16_t recPaddingLength = 0;
113 /* Currently, the padding length is set to 0. If required, the padding length can be customized */
114 if (ctx->config.tlsConfig.recordPaddingCb != NULL) {
115 recPaddingLength =
116 (uint16_t)ctx->config.tlsConfig.recordPaddingCb(ctx, recordType, plainLen,
117 ctx->config.tlsConfig.recordPaddingArg);
118 }
119 #ifdef HITLS_TLS_FEATURE_INDICATOR
120 INDICATOR_MessageIndicate(
121 0, HS_GetVersion(ctx), RECORD_INNER_CONTENT_TYPE, &recordType, 1, ctx, ctx->config.tlsConfig.msgArg);
122 #endif
123
124 /* TlsInnerPlaintext see rfc 8446 section 5.2 */
125
126 /* tlsInnerPlaintext length = content length + record type length (1) + padding length */
127 uint32_t tlsInnerPlaintextLen = plainLen + sizeof(uint8_t) + recPaddingLength;
128 if (tlsInnerPlaintextLen > MAX_PADDING_LEN) {
129 BSL_ERR_PUSH_ERROR(HITLS_REC_RECORD_OVERFLOW);
130 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15669, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
131 "Pack TlsInnerPlaintext length(%u) MUST NOT exceed 2^14 + 1 octets.", tlsInnerPlaintextLen, 0, 0, 0);
132 return HITLS_REC_RECORD_OVERFLOW;
133 }
134
135 uint8_t *tlsInnerPlaintext = BSL_SAL_Calloc(1u, tlsInnerPlaintextLen);
136 if (tlsInnerPlaintext == NULL) {
137 BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL);
138 return RETURN_ERROR_NUMBER_PROCESS(HITLS_MEMALLOC_FAIL, BINLOG_ID17253, "Calloc fail");
139 }
140
141 if (memcpy_s(tlsInnerPlaintext, tlsInnerPlaintextLen, data, plainLen) != EOK) {
142 BSL_SAL_FREE(tlsInnerPlaintext);
143 BSL_ERR_PUSH_ERROR(HITLS_MEMCPY_FAIL);
144 return RETURN_ERROR_NUMBER_PROCESS(HITLS_MEMCPY_FAIL, BINLOG_ID17254, "memcpy fail");
145 }
146
147 tlsInnerPlaintext[plainLen] = recordType;
148
149 /* Padding is calloc when the memory is applied for. Therefore, the number of buffs to be supplemented is 0. You do
150 * not need to perform any operation */
151 recPlaintext->plainLen = tlsInnerPlaintextLen;
152 recPlaintext->plainData = tlsInnerPlaintext;
153 /* tls1.3 Hide the actual record type during encryption */
154 recPlaintext->recordType = (uint8_t)REC_TYPE_APP;
155 #endif /* HITLS_TLS_PROTO_TLS13 */
156 return HITLS_SUCCESS;
157 #else
158 (void)ctx, (void)recordType, (void)data, (void)plainLen, (void)recPlaintext;
159 return HITLS_REC_ERR_NOT_SUPPORT_CIPHER;
160 #endif /* HITLS_TLS_PROTO_TLS */
161 }
162
PlainCalCiphertextLen(const TLS_Ctx * ctx,RecConnSuitInfo * suiteInfo,uint32_t plantextLen,bool isRead)163 static uint32_t PlainCalCiphertextLen(const TLS_Ctx *ctx, RecConnSuitInfo *suiteInfo, uint32_t plantextLen, bool isRead)
164 {
165 (void)ctx;
166 (void)suiteInfo;
167 (void)isRead;
168 return plantextLen;
169 }
PlainCalPlantextBufLen(TLS_Ctx * ctx,RecConnSuitInfo * suiteInfo,uint32_t ciphertextLen,uint32_t * offset,uint32_t * plainLen)170 static int32_t PlainCalPlantextBufLen(TLS_Ctx *ctx, RecConnSuitInfo *suiteInfo,
171 uint32_t ciphertextLen, uint32_t *offset, uint32_t *plainLen)
172 {
173 (void)ctx;
174 (void)suiteInfo;
175 *offset = 0;
176 *plainLen = ciphertextLen;
177 return HITLS_SUCCESS;
178 }
PlainDecrypt(TLS_Ctx * ctx,RecConnState * suiteInfo,const REC_TextInput * cryptMsg,uint8_t * data,uint32_t * dataLen)179 static int32_t PlainDecrypt(TLS_Ctx *ctx, RecConnState *suiteInfo, const REC_TextInput *cryptMsg,
180 uint8_t *data, uint32_t *dataLen)
181 {
182 (void)ctx;
183 (void)suiteInfo;
184 if (memcpy_s(data, *dataLen, cryptMsg->text, cryptMsg->textLen) != EOK) {
185 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15404, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
186 "RecConnDecrypt Failed: memcpy fail.", 0, 0, 0, 0);
187 return HITLS_MEMCPY_FAIL;
188 }
189 // For empty ciphersuite case, the plaintext length is equal to ciphertext length
190 *dataLen = cryptMsg->textLen;
191 return HITLS_SUCCESS;
192 }
193
PlainEncrypt(TLS_Ctx * ctx,RecConnState * state,const REC_TextInput * plainMsg,uint8_t * cipherText,uint32_t cipherTextLen)194 static int32_t PlainEncrypt(TLS_Ctx *ctx, RecConnState *state, const REC_TextInput *plainMsg,
195 uint8_t *cipherText, uint32_t cipherTextLen)
196 {
197 (void)ctx;
198 (void)state;
199 if (memcpy_s(cipherText, cipherTextLen, plainMsg->text, plainMsg->textLen) != EOK) {
200 BSL_ERR_PUSH_ERROR(HITLS_MEMCPY_FAIL);
201 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15926, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
202 "Record:memcpy fail.", 0, 0, 0, 0);
203 return HITLS_MEMCPY_FAIL;
204 }
205 return HITLS_SUCCESS;
206 }
207
UnsupoortDecrypt(TLS_Ctx * ctx,RecConnState * suiteInfo,const REC_TextInput * cryptMsg,uint8_t * data,uint32_t * dataLen)208 static int32_t UnsupoortDecrypt(TLS_Ctx *ctx, RecConnState *suiteInfo, const REC_TextInput *cryptMsg,
209 uint8_t *data, uint32_t *dataLen)
210 {
211 (void)ctx;
212 (void)suiteInfo;
213 (void)cryptMsg;
214 (void)data;
215 (void)dataLen;
216 return HITLS_REC_ERR_NOT_SUPPORT_CIPHER;
217 }
218
UnsupoortEncrypt(TLS_Ctx * ctx,RecConnState * State,const REC_TextInput * plainMsg,uint8_t * cipherText,uint32_t cipherTextLen)219 static int32_t UnsupoortEncrypt(TLS_Ctx *ctx, RecConnState *State, const REC_TextInput *plainMsg,
220 uint8_t *cipherText, uint32_t cipherTextLen)
221 {
222 (void)ctx;
223 (void)State;
224 (void)plainMsg;
225 (void)cipherText;
226 (void)cipherTextLen;
227 return HITLS_REC_ERR_NOT_SUPPORT_CIPHER;
228 }
229
230
RecGetCryptoFuncs(const RecConnSuitInfo * suiteInfo)231 const RecCryptoFunc *RecGetCryptoFuncs(const RecConnSuitInfo *suiteInfo)
232 {
233 static RecCryptoFunc cryptoFuncPlain = {
234 PlainCalCiphertextLen,
235 PlainCalPlantextBufLen,
236 PlainDecrypt,
237 DefaultDecryptPostProcess,
238 PlainEncrypt,
239 DefaultEncryptPreProcess
240 };
241 if (suiteInfo == NULL) {
242 return &cryptoFuncPlain;
243 }
244 switch (suiteInfo->cipherType) {
245 #ifdef HITLS_TLS_SUITE_CIPHER_AEAD
246 case HITLS_AEAD_CIPHER:
247 return RecGetAeadCryptoFuncs(DefaultDecryptPostProcess, DefaultEncryptPreProcess);
248 #endif
249 #ifdef HITLS_TLS_SUITE_CIPHER_CBC
250 case HITLS_CBC_CIPHER:
251 return RecGetCbcCryptoFuncs(DefaultDecryptPostProcess, DefaultEncryptPreProcess);
252 #endif
253 default:
254 break;
255 }
256 BSL_ERR_PUSH_ERROR(HITLS_REC_ERR_NOT_SUPPORT_CIPHER);
257 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16240, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
258 "Internal error, unsupport cipher.", 0, 0, 0, 0);
259 static RecCryptoFunc cryptoFuncUnsupport = {
260 PlainCalCiphertextLen,
261 PlainCalPlantextBufLen,
262 UnsupoortDecrypt,
263 DefaultDecryptPostProcess,
264 UnsupoortEncrypt,
265 DefaultEncryptPreProcess
266 };
267 return &cryptoFuncUnsupport;
268 }
269