• 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 "tls_binlog_id.h"
19 #include "bsl_log_internal.h"
20 #include "bsl_err_internal.h"
21 #include "bsl_bytes.h"
22 #include "hitls_error.h"
23 #include "crypt.h"
24 #include "rec_alert.h"
25 #include "rec_crypto.h"
26 #include "rec_conn.h"
27 
28 
29 #define KEY_EXPANSION_LABEL "key expansion"
30 
31 #ifdef HITLS_TLS_SUITE_CIPHER_CBC
32 #define CBC_MAC_HEADER_LEN 13U
33 #endif
34 
RecConnStateNew(void)35 RecConnState *RecConnStateNew(void)
36 {
37     RecConnState *state = (RecConnState *)BSL_SAL_Calloc(1, sizeof(RecConnState));
38     if (state == NULL) {
39         BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL);
40         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15382, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
41             "Record conn:malloc fail.", 0, 0, 0, 0);
42         return NULL;
43     }
44     return state;
45 }
46 
RecConnStateFree(RecConnState * state)47 void RecConnStateFree(RecConnState *state)
48 {
49     if (state == NULL) {
50         return;
51     }
52     if (state->suiteInfo != NULL) {
53 #ifdef HITLS_TLS_CALLBACK_CRYPT_HMAC_PRIMITIVES
54         SAL_CRYPT_HmacFree(state->suiteInfo->macCtx);
55         state->suiteInfo->macCtx = NULL;
56 #endif
57         SAL_CRYPT_CipherFree(state->suiteInfo->ctx);
58         state->suiteInfo->ctx = NULL;
59     }
60     /* Clear sensitive information */
61     BSL_SAL_CleanseData(state->suiteInfo, sizeof(RecConnSuitInfo));
62     BSL_SAL_FREE(state->suiteInfo);
63     BSL_SAL_FREE(state);
64     return;
65 }
66 
RecConnGetSeqNum(const RecConnState * state)67 uint64_t RecConnGetSeqNum(const RecConnState *state)
68 {
69     return state->seq;
70 }
71 
RecConnSetSeqNum(RecConnState * state,uint64_t seq)72 void RecConnSetSeqNum(RecConnState *state, uint64_t seq)
73 {
74     state->seq = seq;
75 }
76 
77 #ifdef HITLS_TLS_PROTO_DTLS12
RecConnGetEpoch(const RecConnState * state)78 uint16_t RecConnGetEpoch(const RecConnState *state)
79 {
80     return state->epoch;
81 }
82 
RecConnSetEpoch(RecConnState * state,uint16_t epoch)83 void RecConnSetEpoch(RecConnState *state, uint16_t epoch)
84 {
85     state->epoch = epoch;
86 }
87 #endif
88 
RecConnStateSetCipherInfo(RecConnState * state,RecConnSuitInfo * suitInfo)89 int32_t RecConnStateSetCipherInfo(RecConnState *state, RecConnSuitInfo *suitInfo)
90 {
91     if (state->suiteInfo != NULL) {
92         SAL_CRYPT_CipherFree(state->suiteInfo->ctx);
93         state->suiteInfo->ctx = NULL;
94 #ifdef HITLS_TLS_CALLBACK_CRYPT_HMAC_PRIMITIVES
95         SAL_CRYPT_HmacFree(state->suiteInfo->macCtx);
96         state->suiteInfo->macCtx = NULL;
97 #endif
98     }
99     /* Clear sensitive information */
100     BSL_SAL_CleanseData(state->suiteInfo, sizeof(RecConnSuitInfo));
101     // Ensure that no memory leak occurs
102     BSL_SAL_FREE(state->suiteInfo);
103     state->suiteInfo = (RecConnSuitInfo *)BSL_SAL_Malloc(sizeof(RecConnSuitInfo));
104     if (state->suiteInfo == NULL) {
105         BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL);
106         BSL_LOG_BINLOG_FIXLEN(
107             BINLOG_ID15383, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, "Record conn: malloc fail.", 0, 0, 0, 0);
108         return HITLS_MEMALLOC_FAIL;
109     }
110 
111     (void)memcpy_s(state->suiteInfo, sizeof(RecConnSuitInfo), suitInfo, sizeof(RecConnSuitInfo));
112     return HITLS_SUCCESS;
113 }
114 
115 #ifdef HITLS_TLS_SUITE_CIPHER_CBC
RecGetHashAlgoFromMACAlgo(HITLS_MacAlgo macAlgo)116 uint32_t RecGetHashAlgoFromMACAlgo(HITLS_MacAlgo macAlgo)
117 {
118     switch (macAlgo) {
119         case HITLS_MAC_1:
120             return HITLS_HASH_SHA1;
121         case HITLS_MAC_256:
122             return HITLS_HASH_SHA_256;
123         case HITLS_MAC_224:
124             return HITLS_HASH_SHA_224;
125         case HITLS_MAC_384:
126             return HITLS_HASH_SHA_384;
127         case HITLS_MAC_512:
128             return HITLS_HASH_SHA_512;
129 #ifdef HITLS_TLS_PROTO_TLCP11
130         case HITLS_MAC_SM3:
131             return HITLS_HASH_SM3;
132 #endif
133         default:
134             BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15388, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
135                 "CBC encrypt error: unsupport MAC algorithm = %u.", macAlgo, 0, 0, 0);
136             break;
137     }
138     return HITLS_HASH_BUTT;
139 }
140 
RecConnGenerateMac(HITLS_Lib_Ctx * libCtx,const char * attrName,RecConnSuitInfo * suiteInfo,const REC_TextInput * plainMsg,uint8_t * mac,uint32_t * macLen)141 int32_t RecConnGenerateMac(HITLS_Lib_Ctx *libCtx, const char *attrName,
142     RecConnSuitInfo *suiteInfo, const REC_TextInput *plainMsg,
143     uint8_t *mac, uint32_t *macLen)
144 {
145     int32_t ret = HITLS_SUCCESS;
146     uint8_t header[CBC_MAC_HEADER_LEN] = {0};
147     uint32_t offset = 0;
148     if (memcpy_s(header, CBC_MAC_HEADER_LEN, plainMsg->seq, REC_CONN_SEQ_SIZE) != EOK) {  //  sequence or epoch + seq
149         return RETURN_ERROR_NUMBER_PROCESS(HITLS_MEMCPY_FAIL, BINLOG_ID17228, "memcpy fail");
150     }
151     offset += REC_CONN_SEQ_SIZE;
152 
153     header[offset] = plainMsg->type;                                      // The eighth byte is the record type
154     offset++;
155     BSL_Uint16ToByte(plainMsg->version, &header[offset]);                 // The 9th and 10th bytes are version numbers
156     offset += sizeof(uint16_t);
157     BSL_Uint16ToByte((uint16_t)plainMsg->textLen, &header[offset]);       // The 11th and 12th bytes are the data length
158 
159     HITLS_HashAlgo hashAlgo = RecGetHashAlgoFromMACAlgo(suiteInfo->macAlg);
160     if (hashAlgo == HITLS_HASH_BUTT) {
161         return RETURN_ERROR_NUMBER_PROCESS(HITLS_REC_ERR_GENERATE_MAC, BINLOG_ID17229,
162             "RecGetHashAlgoFromMACAlgo fail");
163     }
164 
165     if (suiteInfo->macCtx == NULL) {
166         suiteInfo->macCtx = SAL_CRYPT_HmacInit(libCtx, attrName,
167             hashAlgo, suiteInfo->macKey, suiteInfo->macKeyLen);
168         ret = suiteInfo->macCtx == NULL ? HITLS_REC_ERR_GENERATE_MAC : HITLS_SUCCESS;
169     } else {
170         ret = SAL_CRYPT_HmacReInit(suiteInfo->macCtx);
171     }
172     if (ret != HITLS_SUCCESS) {
173         BSL_ERR_PUSH_ERROR(HITLS_REC_ERR_GENERATE_MAC);
174         return RETURN_ERROR_NUMBER_PROCESS(HITLS_REC_ERR_GENERATE_MAC, BINLOG_ID15389, "SAL_CRYPT_HmacInit fail");
175     }
176 
177     ret = SAL_CRYPT_HmacUpdate(suiteInfo->macCtx, header, CBC_MAC_HEADER_LEN);
178     if (ret != HITLS_SUCCESS) {
179         return RETURN_ERROR_NUMBER_PROCESS(ret, BINLOG_ID17230, "HmacUpdate fail");
180     }
181 
182     ret = SAL_CRYPT_HmacUpdate(suiteInfo->macCtx, plainMsg->text, plainMsg->textLen);
183     if (ret != HITLS_SUCCESS) {
184         return RETURN_ERROR_NUMBER_PROCESS(ret, BINLOG_ID17231, "HmacUpdate fail");
185     }
186 
187     ret = SAL_CRYPT_HmacFinal(suiteInfo->macCtx, mac, macLen);
188     if (ret != HITLS_SUCCESS) {
189         return RETURN_ERROR_NUMBER_PROCESS(ret, BINLOG_ID17232, "HmacFinal fail");
190     }
191     return HITLS_SUCCESS;
192 }
193 
RecConnInitGenerateMacInput(const REC_TextInput * in,const uint8_t * text,uint32_t textLen,REC_TextInput * out)194 void RecConnInitGenerateMacInput(const REC_TextInput *in, const uint8_t *text, uint32_t textLen,
195     REC_TextInput *out)
196 {
197     out->version = in->version;
198     out->negotiatedVersion = in->negotiatedVersion;
199 #ifdef HITLS_TLS_FEATURE_ETM
200     out->isEncryptThenMac = in->isEncryptThenMac;
201 #endif
202     out->type = in->type;
203     out->text = text;
204     out->textLen = textLen;
205     for (uint32_t i = 0u; i < REC_CONN_SEQ_SIZE; i++) {
206         out->seq[i] = in->seq[i];
207     }
208 }
209 
RecConnCheckMac(TLS_Ctx * ctx,RecConnSuitInfo * suiteInfo,const REC_TextInput * cryptMsg,const uint8_t * text,uint32_t textLen)210 int32_t RecConnCheckMac(TLS_Ctx *ctx, RecConnSuitInfo *suiteInfo, const REC_TextInput *cryptMsg,
211     const uint8_t *text, uint32_t textLen)
212 {
213     REC_TextInput input = {0};
214     uint8_t mac[MAX_DIGEST_SIZE] = {0};
215     uint32_t macLen = MAX_DIGEST_SIZE;
216     RecConnInitGenerateMacInput(cryptMsg, text, textLen - suiteInfo->macLen, &input);
217     int32_t ret = RecConnGenerateMac(LIBCTX_FROM_CTX(ctx), ATTRIBUTE_FROM_CTX(ctx),
218         suiteInfo, &input, mac, &macLen);
219     if (ret != HITLS_SUCCESS) {
220         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID17233, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
221             "RecConnGenerateMac fail.", 0, 0, 0, 0);
222         return RecordSendAlertMsg(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR);
223     }
224     if (macLen != suiteInfo->macLen) {
225         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15929, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
226             "record cbc mode decrypt error: macLen = %u, required len = %u.",
227             macLen, suiteInfo->macLen, 0, 0);
228         return RecordSendAlertMsg(ctx, ALERT_LEVEL_FATAL, ALERT_BAD_RECORD_MAC);
229     }
230 
231     if (memcmp(&text[textLen - suiteInfo->macLen], mac, macLen) != 0) {
232         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15942, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
233             "record cbc mode decrypt error: MAC check failed.", 0, 0, 0, 0);
234         return RecordSendAlertMsg(ctx, ALERT_LEVEL_FATAL, ALERT_BAD_RECORD_MAC);
235     }
236     return HITLS_SUCCESS;
237 }
238 #endif /* HITLS_TLS_SUITE_CIPHER_CBC */
RecConnEncrypt(TLS_Ctx * ctx,RecConnState * state,const REC_TextInput * plainMsg,uint8_t * cipherText,uint32_t cipherTextLen)239 int32_t RecConnEncrypt(TLS_Ctx *ctx, RecConnState *state, const REC_TextInput *plainMsg, uint8_t *cipherText, uint32_t cipherTextLen)
240 {
241     return RecGetCryptoFuncs(state->suiteInfo)->encryt(ctx, state, plainMsg, cipherText, cipherTextLen);
242 }
243 
RecConnDecrypt(TLS_Ctx * ctx,RecConnState * state,const REC_TextInput * cryptMsg,uint8_t * data,uint32_t * dataLen)244 int32_t RecConnDecrypt(TLS_Ctx *ctx, RecConnState *state, const REC_TextInput *cryptMsg, uint8_t *data,
245     uint32_t *dataLen)
246 {
247     const RecCryptoFunc *funcs = RecGetCryptoFuncs(state->suiteInfo);
248     uint32_t ciphertextLen = funcs->calCiphertextLen(ctx, state->suiteInfo, 0, true);
249     // The length of the record body to be decrypted must be greater than or equal to ciphertextLen
250     if (cryptMsg->textLen < ciphertextLen) {
251         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15403, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
252             "RecConnDecrypt Failed: record body length to be decrypted is %u, lower bound of ciphertext len is %u",
253             cryptMsg->textLen, ciphertextLen, 0, 0);
254         return RecordSendAlertMsg(ctx, ALERT_LEVEL_FATAL, ALERT_BAD_RECORD_MAC);
255     }
256     return funcs->decrypt(ctx, state, cryptMsg, data, dataLen);
257 }
258 
PackSuitInfo(RecConnSuitInfo * suitInfo,const REC_SecParameters * param)259 static void PackSuitInfo(RecConnSuitInfo *suitInfo, const REC_SecParameters *param)
260 {
261     suitInfo->macAlg = param->macAlg;
262     suitInfo->cipherAlg = param->cipherAlg;
263     suitInfo->cipherType = param->cipherType;
264     suitInfo->fixedIvLength = param->fixedIvLength;
265     suitInfo->encKeyLen = param->encKeyLen;
266     suitInfo->macKeyLen = param->macKeyLen;
267     suitInfo->blockLength = param->blockLength;
268     suitInfo->recordIvLength = param->recordIvLength;
269     suitInfo->macLen = param->macLen;
270     return;
271 }
272 
RecConnCalcWriteKey(const REC_SecParameters * param,uint8_t * keyBuf,uint32_t keyBufLen,RecConnSuitInfo * client,RecConnSuitInfo * server)273 static void RecConnCalcWriteKey(const REC_SecParameters *param, uint8_t *keyBuf, uint32_t keyBufLen,
274                                 RecConnSuitInfo *client, RecConnSuitInfo *server)
275 {
276     if (keyBufLen == 0) {
277         return;
278     }
279     uint32_t offset = 0;
280     uint32_t totalOffset = 2 * param->macKeyLen + 2 * param->encKeyLen + 2 * param->fixedIvLength;
281     if (keyBufLen < totalOffset) {
282         return;
283     }
284 
285     if (param->macKeyLen > 0u) {
286         if (memcpy_s(client->macKey, sizeof(client->macKey), keyBuf, param->macKeyLen) != EOK) {
287             return;
288         }
289         offset += param->macKeyLen;
290         if (memcpy_s(server->macKey, sizeof(server->macKey), keyBuf + offset, param->macKeyLen) != EOK) {
291             return;
292         }
293         offset += param->macKeyLen;
294     }
295     if (param->encKeyLen > 0u) {
296         if (memcpy_s(client->key, sizeof(client->key), keyBuf + offset, param->encKeyLen) != EOK) {
297             return;
298         }
299         offset += param->encKeyLen;
300         if (memcpy_s(server->key, sizeof(server->key), keyBuf + offset, param->encKeyLen) != EOK) {
301             return;
302         }
303         offset += param->encKeyLen;
304     }
305     if (param->fixedIvLength > 0u) {
306         if (memcpy_s(client->iv, sizeof(client->iv), keyBuf + offset, param->fixedIvLength) != EOK) {
307             return;
308         }
309         offset += param->fixedIvLength;
310         if (memcpy_s(server->iv, sizeof(server->iv), keyBuf + offset, param->fixedIvLength) != EOK) {
311             return;
312         }
313     }
314     PackSuitInfo(client, param);
315     PackSuitInfo(server, param);
316 }
317 
RecConnKeyBlockGen(HITLS_Lib_Ctx * libCtx,const char * attrName,const REC_SecParameters * param,RecConnSuitInfo * client,RecConnSuitInfo * server)318 int32_t RecConnKeyBlockGen(HITLS_Lib_Ctx *libCtx, const char *attrName,
319     const REC_SecParameters *param, RecConnSuitInfo *client, RecConnSuitInfo *server)
320 {
321     /** Calculate the key length: 2MAC, 2key, 2IV  */
322     uint32_t keyLen = ((uint32_t)param->macKeyLen * 2) + ((uint32_t)param->encKeyLen * 2) +
323         ((uint32_t)param->fixedIvLength * 2);
324     if (keyLen == 0u || param->macKeyLen > sizeof(client->macKey) ||
325         param->encKeyLen > sizeof(client->key) || param->fixedIvLength > sizeof(client->iv)) {
326         BSL_ERR_PUSH_ERROR(HITLS_REC_ERR_NOT_SUPPORT_CIPHER);
327         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15943, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
328             "Record Key: not support--length is invalid.", 0, 0, 0, 0);
329         return HITLS_REC_ERR_NOT_SUPPORT_CIPHER;
330     }
331 
332     /*  Based on RFC5246 6.3
333         key_block = PRF(SecurityParameters.master_secret, "key expansion", SecurityParameters.server_random +
334                     SecurityParameters.client_random);
335     */
336     CRYPT_KeyDeriveParameters keyDeriveParam = {0};
337     keyDeriveParam.hashAlgo = param->prfAlg;
338     keyDeriveParam.secret = param->masterSecret;
339     keyDeriveParam.secretLen = REC_MASTER_SECRET_LEN;
340     keyDeriveParam.label = (const uint8_t *)KEY_EXPANSION_LABEL;
341     keyDeriveParam.labelLen = strlen(KEY_EXPANSION_LABEL);
342     keyDeriveParam.libCtx = libCtx;
343     keyDeriveParam.attrName = attrName;
344 
345     uint8_t randomValue[REC_RANDOM_LEN * 2];
346     /** Random value of the replication server */
347     (void)memcpy_s(randomValue, sizeof(randomValue), param->serverRandom, REC_RANDOM_LEN);
348     /** Random value of the replication client */
349     (void)memcpy_s(&randomValue[REC_RANDOM_LEN], sizeof(randomValue) - REC_RANDOM_LEN,
350         param->clientRandom, REC_RANDOM_LEN);
351 
352     keyDeriveParam.seed = randomValue;
353     // Total length of 2 random numbers
354     keyDeriveParam.seedLen = REC_RANDOM_LEN * 2;
355 
356     /** Maximum key length: 2MAC, 2key, 2IV */
357     uint8_t keyBuf[REC_MAX_KEY_BLOCK_LEN];
358     int32_t ret = SAL_CRYPT_PRF(&keyDeriveParam, keyBuf, keyLen);
359     if (ret != HITLS_SUCCESS) {
360         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15944, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
361             "Record Key:generate fail.", 0, 0, 0, 0);
362         return ret;
363     }
364 
365     RecConnCalcWriteKey(param, keyBuf, REC_MAX_KEY_BLOCK_LEN, client, server);
366     BSL_SAL_CleanseData(keyBuf, sizeof(keyBuf));
367     return HITLS_SUCCESS;
368 }
369 
370 #ifdef HITLS_TLS_PROTO_TLS13
RecTLS13CalcWriteKey(CRYPT_KeyDeriveParameters * deriveInfo,uint8_t * key,uint32_t keyLen)371 int32_t RecTLS13CalcWriteKey(CRYPT_KeyDeriveParameters *deriveInfo, uint8_t *key, uint32_t keyLen)
372 {
373     uint8_t label[] = "key";
374     deriveInfo->label = label;
375     deriveInfo->labelLen = sizeof(label) - 1;
376     return SAL_CRYPT_HkdfExpandLabel(deriveInfo, key, keyLen);
377 }
378 
RecTLS13CalcWriteIv(CRYPT_KeyDeriveParameters * deriveInfo,uint8_t * iv,uint32_t ivLen)379 int32_t RecTLS13CalcWriteIv(CRYPT_KeyDeriveParameters *deriveInfo, uint8_t *iv, uint32_t ivLen)
380 {
381     uint8_t label[] = "iv";
382     deriveInfo->label = label;
383     deriveInfo->labelLen = sizeof(label) - 1;
384     return SAL_CRYPT_HkdfExpandLabel(deriveInfo, iv, ivLen);
385 }
386 
RecTLS13ConnKeyBlockGen(HITLS_Lib_Ctx * libCtx,const char * attrName,const REC_SecParameters * param,RecConnSuitInfo * suitInfo)387 int32_t RecTLS13ConnKeyBlockGen(HITLS_Lib_Ctx *libCtx, const char *attrName,
388     const REC_SecParameters *param, RecConnSuitInfo *suitInfo)
389 {
390     const uint8_t *secret = (const uint8_t *)param->masterSecret;
391     uint32_t secretLen = SAL_CRYPT_DigestSize(param->prfAlg);
392     if (secretLen == 0) {
393         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID17234, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, "DigestSize err", 0, 0, 0, 0);
394         return HITLS_CRYPT_ERR_DIGEST;
395     }
396     uint32_t keyLen = param->encKeyLen;
397     uint32_t ivLen = param->fixedIvLength;
398 
399     if (secretLen > sizeof(param->masterSecret) || keyLen > sizeof(suitInfo->key) || ivLen > sizeof(suitInfo->iv)) {
400         BSL_ERR_PUSH_ERROR(HITLS_REC_ERR_NOT_SUPPORT_CIPHER);
401         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15408, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
402             "length is invalid.", 0, 0, 0, 0);
403         return HITLS_REC_ERR_NOT_SUPPORT_CIPHER;
404     }
405     CRYPT_KeyDeriveParameters deriveInfo = {0};
406     deriveInfo.hashAlgo = param->prfAlg;
407     deriveInfo.secret = secret;
408     deriveInfo.secretLen = secretLen;
409     deriveInfo.libCtx = libCtx;
410     deriveInfo.attrName = attrName;
411     int32_t ret = RecTLS13CalcWriteKey(&deriveInfo, suitInfo->key, keyLen);
412     if (ret != HITLS_SUCCESS) {
413         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID17235, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
414             "CalcWriteKey fail", 0, 0, 0, 0);
415         return ret;
416     }
417 
418     ret = RecTLS13CalcWriteIv(&deriveInfo, suitInfo->iv, ivLen);
419     if (ret != HITLS_SUCCESS) {
420         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID17236, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
421             "CalcWriteIv fail", 0, 0, 0, 0);
422         return ret;
423     }
424 
425     PackSuitInfo(suitInfo, param);
426     return HITLS_SUCCESS;
427 }
428 #endif /* HITLS_TLS_PROTO_TLS13 */