• 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 #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