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 #ifdef HITLS_TLS_FEATURE_SESSION_TICKET
17 #include <stdbool.h>
18 #include <string.h>
19 #include "securec.h"
20 #include "tlv.h"
21 #include "bsl_log_internal.h"
22 #include "bsl_log.h"
23 #include "bsl_err_internal.h"
24 #include "tls_binlog_id.h"
25 #include "bsl_bytes.h"
26 #include "bsl_sal.h"
27 #include "crypt.h"
28 #include "hitls_error.h"
29 #include "session_type.h"
30 #include "session_enc.h"
31
32 typedef struct {
33 uint8_t keyName[HITLS_TICKET_KEY_NAME_SIZE];
34 uint8_t iv[HITLS_TICKET_IV_SIZE];
35 uint32_t encryptedStateSize;
36 uint8_t *encryptedState;
37 uint8_t mac[HITLS_TICKET_KEY_SIZE];
38 } Ticket;
39
40 #define DEFAULT_SESSION_ENCRYPT_TYPE HITLS_AEAD_CIPHER
41 #define DEFAULT_SESSION_ENCRYPT_ALGO HITLS_CIPHER_AES_256_GCM
42 #ifdef HITLS_TLS_SUITE_CIPHER_CBC
43 #define AES_CBC_BLOCK_LEN 16u
44 #endif
45
SetCipherInfo(const TLS_SessionMgr * sessMgr,Ticket * ticket,HITLS_CipherParameters * cipher)46 static void SetCipherInfo(const TLS_SessionMgr *sessMgr, Ticket *ticket, HITLS_CipherParameters *cipher)
47 {
48 cipher->type = DEFAULT_SESSION_ENCRYPT_TYPE;
49 cipher->algo = DEFAULT_SESSION_ENCRYPT_ALGO;
50 cipher->key = sessMgr->ticketAesKey;
51 cipher->keyLen = HITLS_TICKET_KEY_SIZE;
52 cipher->iv = ticket->iv;
53 cipher->ivLen = HITLS_TICKET_IV_SIZE;
54 cipher->aad = ticket->iv;
55 cipher->aadLen = HITLS_TICKET_IV_SIZE;
56 return;
57 }
58
GetSessEncryptInfo(TLS_Ctx * ctx,const TLS_SessionMgr * sessMgr,Ticket * ticket,HITLS_CipherParameters * cipher)59 static int32_t GetSessEncryptInfo(TLS_Ctx *ctx, const TLS_SessionMgr *sessMgr, Ticket *ticket, HITLS_CipherParameters *cipher)
60 {
61 int32_t ret;
62 #ifdef HITLS_TLS_FEATURE_SESSION
63 HITLS_TicketKeyCb cb = sessMgr->ticketKeyCb;
64 if (cb != NULL) {
65 ret = cb(ticket->keyName, HITLS_TICKET_KEY_NAME_SIZE, cipher, true);
66 if (memcpy_s(ticket->iv, HITLS_TICKET_IV_SIZE, cipher->iv, cipher->ivLen) != EOK) {
67 BSL_ERR_PUSH_ERROR(HITLS_TICKET_KEY_RET_FAIL);
68 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16069, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
69 "iv copy fail when GetSessEncryptInfo.", 0, 0, 0, 0);
70 return HITLS_TICKET_KEY_RET_FAIL;
71 }
72 return ret;
73 }
74 #endif
75 /* The user does not register the callback. The default ticket key is used. */
76 (void)memcpy_s(ticket->keyName, HITLS_TICKET_KEY_NAME_SIZE, sessMgr->ticketKeyName, HITLS_TICKET_KEY_NAME_SIZE);
77
78 ret = SAL_CRYPT_Rand(LIBCTX_FROM_CTX(ctx), ticket->iv, HITLS_TICKET_IV_SIZE);
79 if (ret != HITLS_SUCCESS) {
80 BSL_ERR_PUSH_ERROR(HITLS_TICKET_KEY_RET_FAIL);
81 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16021, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, "Rand fail", 0, 0, 0, 0);
82 return HITLS_TICKET_KEY_RET_FAIL;
83 }
84
85 SetCipherInfo(sessMgr, ticket, cipher);
86
87 return HITLS_TICKET_KEY_RET_SUCCESS;
88 }
89
PackKeyNameAndIv(const Ticket * ticket,uint8_t * data,uint32_t len,uint32_t * usedLen)90 static int32_t PackKeyNameAndIv(const Ticket *ticket, uint8_t *data, uint32_t len, uint32_t *usedLen)
91 {
92 uint32_t offset = 0;
93 if (memcpy_s(&data[0], len, ticket->keyName, HITLS_TICKET_KEY_NAME_SIZE) != EOK) {
94 BSL_ERR_PUSH_ERROR(HITLS_MEMCPY_FAIL);
95 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16022, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
96 "copy keyName fail when encrypt session ticket.", 0, 0, 0, 0);
97 return HITLS_MEMCPY_FAIL;
98 }
99 offset += HITLS_TICKET_KEY_NAME_SIZE;
100
101 if (memcpy_s(&data[offset], len - offset, ticket->iv, HITLS_TICKET_IV_SIZE) != EOK) {
102 BSL_ERR_PUSH_ERROR(HITLS_MEMCPY_FAIL);
103 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16023, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
104 "copy iv fail when encrypt session ticket.", 0, 0, 0, 0);
105 return HITLS_MEMCPY_FAIL;
106 }
107 offset += HITLS_TICKET_IV_SIZE;
108
109 *usedLen = offset;
110 return HITLS_SUCCESS;
111 }
112 #ifdef HITLS_TLS_SUITE_CIPHER_CBC
GetCbcPendingLen(uint32_t encodeLen,uint8_t * paddingLen)113 static uint32_t GetCbcPendingLen(uint32_t encodeLen, uint8_t *paddingLen)
114 {
115 *paddingLen = (encodeLen + sizeof(uint8_t)) % AES_CBC_BLOCK_LEN;
116 if (*paddingLen != 0) {
117 *paddingLen = AES_CBC_BLOCK_LEN - *paddingLen;
118 }
119 return *paddingLen + sizeof(uint8_t);
120 }
121 #endif
PackEncryptTicket(HITLS_Lib_Ctx * libCtx,const char * attrName,const HITLS_Session * sess,HITLS_CipherParameters * cipher,uint8_t * data,uint32_t len,uint32_t * usedLen)122 static int32_t PackEncryptTicket(HITLS_Lib_Ctx *libCtx, const char *attrName,
123 const HITLS_Session *sess, HITLS_CipherParameters *cipher, uint8_t *data, uint32_t len, uint32_t *usedLen)
124 {
125 int32_t ret = 0;
126 /* Encode the session. */
127 uint32_t encodeLen = SESS_GetTotalEncodeSize(sess);
128 uint32_t plaintextLen = encodeLen;
129 #ifdef HITLS_TLS_SUITE_CIPHER_CBC
130 uint8_t paddingLen = 0;
131 if (cipher->type == HITLS_CBC_CIPHER) {
132 /* In CBC mode, the padding needs to be calculated. */
133 /* Plain text length plus padding length */
134 plaintextLen += GetCbcPendingLen(encodeLen, &paddingLen);
135 }
136 #endif
137
138 uint8_t *plaintext = BSL_SAL_Calloc(1u, plaintextLen);
139 if (plaintext == NULL) {
140 BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL);
141 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16024, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
142 "encData malloc fail when encrypt session ticket.", 0, 0, 0, 0);
143 return HITLS_MEMALLOC_FAIL;
144 }
145 ret = SESS_Encode(sess, plaintext, plaintextLen, &plaintextLen);
146 if (ret != HITLS_SUCCESS) {
147 BSL_SAL_CleanseData(plaintext, plaintextLen);
148 BSL_SAL_FREE(plaintext);
149 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16025, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
150 "SESS_Encode fail when encrypt session ticket.", 0, 0, 0, 0);
151 return ret;
152 }
153
154 #ifdef HITLS_TLS_SUITE_CIPHER_CBC
155 /* Padding is required in CBC mode. */
156 if (cipher->type == HITLS_CBC_CIPHER) {
157 /* The last byte is the padding length field, and the padding content is the length value. */
158 uint32_t count = paddingLen + sizeof(uint8_t);
159 /* The calculation is accurate when the memory is applied for the plaintext. Therefore, the
160 * return value does not need to be checked. */
161 (void)memset_s(&plaintext[encodeLen], count, paddingLen, count);
162 plaintextLen += count;
163 }
164 #endif
165 uint32_t offset = 0;
166 /* reserved length field */
167 offset += sizeof(uint32_t);
168 /* Encrypt and fill the ticket. */
169 uint32_t encryptLen = len - offset;
170 ret = SAL_CRYPT_Encrypt(libCtx, attrName, cipher, plaintext, plaintextLen, &data[offset], &encryptLen);
171 BSL_SAL_CleanseData(plaintext, plaintextLen);
172 BSL_SAL_FREE(plaintext);
173 if (ret != HITLS_SUCCESS) {
174 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16026, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
175 "SAL_CRYPT_Encrypt fail when encrypt session ticket.", 0, 0, 0, 0);
176 return ret;
177 }
178 /* padding length */
179 BSL_Uint32ToByte(encryptLen, &data[offset - sizeof(uint32_t)]);
180 offset += encryptLen;
181
182 *usedLen = offset;
183 return HITLS_SUCCESS;
184 }
185
186 #ifdef HITLS_TLS_SUITE_CIPHER_CBC
PackTicketHmac(HITLS_Lib_Ctx * libCtx,const char * attrName,HITLS_CipherParameters * cipher,uint8_t * data,uint32_t len,uint32_t offset,uint32_t * usedLen)187 static int32_t PackTicketHmac(HITLS_Lib_Ctx *libCtx, const char *attrName,
188 HITLS_CipherParameters *cipher, uint8_t *data, uint32_t len, uint32_t offset,
189 uint32_t *usedLen)
190 {
191 /* The HMAC field is filled only in CBC mode. In other modes, the HMAC field is returned. */
192 if (cipher->type != HITLS_CBC_CIPHER) {
193 *usedLen = 0;
194 return HITLS_SUCCESS;
195 }
196
197 int32_t ret;
198 uint8_t mac[HITLS_TICKET_KEY_SIZE] = {0};
199 uint32_t macLen = HITLS_TICKET_KEY_SIZE;
200 ret = SAL_CRYPT_Hmac(libCtx, attrName,
201 HITLS_HASH_SHA_256, cipher->hmacKey, cipher->hmacKeyLen, data, offset, mac, &macLen);
202 if (ret != HITLS_SUCCESS) {
203 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16027, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
204 "TicketHmac fail when encrypt session ticket.", 0, 0, 0, 0);
205 return ret;
206 }
207 if (memcpy_s(&data[offset], len - offset, mac, macLen) != EOK) {
208 BSL_ERR_PUSH_ERROR(HITLS_MEMCPY_FAIL);
209 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16028, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
210 "copy mac fail when encrypt session ticket.", 0, 0, 0, 0);
211 return HITLS_MEMCPY_FAIL;
212 }
213 *usedLen = macLen;
214 return HITLS_SUCCESS;
215 }
216 #endif /* HITLS_TLS_SUITE_CIPHER_CBC */
217
NewTicketBuf(const HITLS_Session * sess,HITLS_CipherParameters * cipher,uint32_t * ticketBufSize)218 static uint8_t *NewTicketBuf(const HITLS_Session *sess, HITLS_CipherParameters *cipher, uint32_t *ticketBufSize)
219 {
220 (void)cipher;
221 uint32_t encodeLen = SESS_GetTotalEncodeSize(sess);
222 uint32_t plaintextLen = encodeLen;
223 #ifdef HITLS_TLS_SUITE_CIPHER_CBC
224 if (cipher->type == HITLS_CBC_CIPHER) {
225 /* In CBC mode, the padding needs to be calculated. */
226 uint8_t paddingLen = (encodeLen + sizeof(uint8_t)) % AES_CBC_BLOCK_LEN;
227 if (paddingLen != 0) {
228 paddingLen = AES_CBC_BLOCK_LEN - paddingLen;
229 }
230 /* Plain text length plus padding length */
231 plaintextLen += paddingLen + sizeof(uint8_t);
232 }
233 #endif
234 /* Plain text length plus key name, iv, encrypted data length, and MAC length. */
235 plaintextLen += HITLS_TICKET_KEY_NAME_SIZE + HITLS_TICKET_IV_SIZE + sizeof(uint32_t) + HITLS_TICKET_KEY_SIZE;
236
237 uint8_t *ticketBuf = BSL_SAL_Calloc(1u, plaintextLen);
238 if (ticketBuf == NULL) {
239 BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL);
240 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16029, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
241 "ticketBuf malloc fail when encrypt session ticket.", 0, 0, 0, 0);
242 return NULL;
243 }
244
245 *ticketBufSize = plaintextLen;
246 return ticketBuf;
247 }
248
SESSMGR_EncryptSessionTicket(TLS_Ctx * ctx,const TLS_SessionMgr * sessMgr,const HITLS_Session * sess,uint8_t ** ticketBuf,uint32_t * ticketBufSize)249 int32_t SESSMGR_EncryptSessionTicket(TLS_Ctx *ctx,
250 const TLS_SessionMgr *sessMgr, const HITLS_Session *sess, uint8_t **ticketBuf, uint32_t *ticketBufSize)
251 {
252 if (sessMgr == NULL || sess == NULL || ticketBuf == NULL) {
253 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16713, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, "input null", 0, 0, 0, 0);
254 return HITLS_INTERNAL_EXCEPTION;
255 }
256
257 Ticket ticket = {0};
258 HITLS_CipherParameters cipher = {0};
259 int32_t retVal = GetSessEncryptInfo(ctx, sessMgr, &ticket, &cipher);
260 if (retVal < 0) {
261 BSL_ERR_PUSH_ERROR(HITLS_SESS_ERR_SESSION_TICKET_KEY_FAIL);
262 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16030, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
263 "GetSessEncryptInfo fail when encrypt session ticket.", 0, 0, 0, 0);
264 return HITLS_SESS_ERR_SESSION_TICKET_KEY_FAIL;
265 }
266 if (retVal == HITLS_TICKET_KEY_RET_FAIL) {
267 /* Failed to obtain the encryption information. An empty ticket is returned. */
268 *ticketBufSize = 0;
269 return HITLS_SUCCESS;
270 }
271
272 uint32_t dataLen = 0;
273 uint8_t *data = NewTicketBuf(sess, &cipher, &dataLen);
274 if (data == NULL) {
275 return HITLS_MEMALLOC_FAIL;
276 }
277 /* Fill in the key name and iv. */
278 int32_t ret;
279 uint32_t packLen = 0;
280 uint32_t offset = 0;
281 ret = PackKeyNameAndIv(&ticket, &data[0], dataLen, &packLen);
282 if (ret != HITLS_SUCCESS) {
283 BSL_SAL_FREE(data);
284 return ret;
285 }
286 offset += packLen;
287 /* Encrypt and fill the ticket. */
288 ret = PackEncryptTicket(LIBCTX_FROM_CTX(ctx), ATTRIBUTE_FROM_CTX(ctx),
289 sess, &cipher, &data[offset], dataLen - offset, &packLen);
290 if (ret != HITLS_SUCCESS) {
291 BSL_SAL_FREE(data);
292 return ret;
293 }
294 offset += packLen;
295
296 #ifdef HITLS_TLS_SUITE_CIPHER_CBC
297 /* fill HMAC */
298 ret = PackTicketHmac(LIBCTX_FROM_CTX(ctx), ATTRIBUTE_FROM_CTX(ctx),
299 &cipher, data, dataLen, offset, &packLen);
300 if (ret != HITLS_SUCCESS) {
301 BSL_SAL_FREE(data);
302 return ret;
303 }
304 offset += packLen;
305 #endif
306 *ticketBufSize = offset;
307 *ticketBuf = data;
308 return HITLS_SUCCESS;
309 }
ParseSessionTicket(Ticket * ticket,const uint8_t * ticketBuf,uint32_t ticketBufSize)310 static int32_t ParseSessionTicket(Ticket *ticket, const uint8_t *ticketBuf, uint32_t ticketBufSize)
311 {
312 uint32_t offset = 0;
313 if (ticketBufSize < HITLS_TICKET_KEY_NAME_SIZE + HITLS_TICKET_IV_SIZE + sizeof(uint32_t)) {
314 BSL_ERR_PUSH_ERROR(HITLS_SESS_ERR_SESSION_TICKET_SIZE_INCORRECT);
315 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16044, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
316 "ticketBufSize is incorrect when parse session ticket.", 0, 0, 0, 0);
317 return HITLS_SESS_ERR_SESSION_TICKET_SIZE_INCORRECT;
318 }
319
320 (void)memcpy_s(ticket->keyName, HITLS_TICKET_KEY_NAME_SIZE, ticketBuf, HITLS_TICKET_KEY_NAME_SIZE);
321 offset += HITLS_TICKET_KEY_NAME_SIZE;
322
323 (void)memcpy_s(ticket->iv, HITLS_TICKET_IV_SIZE, &ticketBuf[offset], HITLS_TICKET_IV_SIZE);
324 offset += HITLS_TICKET_IV_SIZE;
325
326 ticket->encryptedStateSize = BSL_ByteToUint32(&ticketBuf[offset]);
327 offset += sizeof(uint32_t);
328
329 if ((ticketBufSize - offset) < ticket->encryptedStateSize) {
330 BSL_ERR_PUSH_ERROR(HITLS_SESS_ERR_SESSION_TICKET_SIZE_INCORRECT);
331 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16032, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
332 "ticketBufSize is incorrect when parse session ticket encryptedStateSize.", 0, 0, 0, 0);
333 return HITLS_SESS_ERR_SESSION_TICKET_SIZE_INCORRECT;
334 }
335
336 ticket->encryptedState = (uint8_t *)(uintptr_t)&ticketBuf[offset];
337 offset += ticket->encryptedStateSize;
338
339 if (ticketBufSize != offset) {
340 if ((ticketBufSize - offset) != HITLS_TICKET_KEY_SIZE) {
341 BSL_ERR_PUSH_ERROR(HITLS_SESS_ERR_SESSION_TICKET_SIZE_INCORRECT);
342 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16033, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
343 "ticketBufSize is incorrect when parse session ticket hmac.", 0, 0, 0, 0);
344 return HITLS_SESS_ERR_SESSION_TICKET_SIZE_INCORRECT;
345 }
346 (void)memcpy_s(ticket->mac, HITLS_TICKET_KEY_SIZE, &ticketBuf[offset], HITLS_TICKET_KEY_SIZE);
347 }
348
349 return HITLS_SUCCESS;
350 }
351
GetSessDecryptInfo(const TLS_SessionMgr * sessMgr,Ticket * ticket,HITLS_CipherParameters * cipher)352 static int32_t GetSessDecryptInfo(const TLS_SessionMgr *sessMgr, Ticket *ticket, HITLS_CipherParameters *cipher)
353 {
354 #ifdef HITLS_TLS_FEATURE_SESSION
355 HITLS_TicketKeyCb cb = sessMgr->ticketKeyCb;
356 if (cb != NULL) {
357 return cb(ticket->keyName, HITLS_TICKET_KEY_NAME_SIZE, cipher, false);
358 }
359 #endif
360 /* The user does not register the callback. Use the default ticket key. */
361 if (memcmp(ticket->keyName, sessMgr->ticketKeyName, HITLS_TICKET_KEY_NAME_SIZE) != 0) {
362 /* Failed to match the key name. */
363 return HITLS_TICKET_KEY_RET_FAIL;
364 }
365 SetCipherInfo(sessMgr, ticket, cipher);
366 return HITLS_TICKET_KEY_RET_SUCCESS;
367 }
368
369 #ifdef HITLS_TLS_SUITE_CIPHER_CBC
CheckTicketHmac(HITLS_Lib_Ctx * libCtx,const char * attrName,HITLS_CipherParameters * cipher,Ticket * ticket,const uint8_t * data,uint32_t len,bool * isPass)370 static int32_t CheckTicketHmac(HITLS_Lib_Ctx *libCtx, const char *attrName,
371 HITLS_CipherParameters *cipher, Ticket *ticket, const uint8_t *data, uint32_t len, bool *isPass)
372 {
373 /* The HMAC check is required only in CBC mode. In other modes, the HMAC check is returned. */
374 if (cipher->type != HITLS_CBC_CIPHER) {
375 *isPass = true;
376 return HITLS_SUCCESS;
377 }
378
379 int32_t ret;
380 uint8_t mac[HITLS_TICKET_KEY_SIZE] = {0};
381 uint32_t macLen = HITLS_TICKET_KEY_SIZE;
382 ret = SAL_CRYPT_Hmac(libCtx, attrName,
383 HITLS_HASH_SHA_256, cipher->hmacKey, cipher->hmacKeyLen, data, len - HITLS_TICKET_KEY_SIZE, mac, &macLen);
384 if (ret != HITLS_SUCCESS) {
385 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16035, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
386 "TicketHmac fail when decrypt session ticket.", 0, 0, 0, 0);
387 return ret;
388 }
389
390 if (memcmp(ticket->mac, mac, macLen) != 0) {
391 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16036, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN,
392 "compare mac fail when decrypt session ticket.", 0, 0, 0, 0);
393 /* The HMAC check fails, but the complete link establishment can be continued. Therefore, HITLS_SUCCESS is
394 * returned. */
395 *isPass = false;
396 return HITLS_SUCCESS;
397 }
398 *isPass = true;
399 return HITLS_SUCCESS;
400 }
401 #endif /* HITLS_TLS_SUITE_CIPHER_CBC */
402
GenerateSessFromTicket(HITLS_Lib_Ctx * libCtx,const char * attrName,HITLS_CipherParameters * cipher,Ticket * ticket,uint32_t ticketBufSize,HITLS_Session ** sess)403 static int32_t GenerateSessFromTicket(HITLS_Lib_Ctx *libCtx, const char *attrName,
404 HITLS_CipherParameters *cipher, Ticket *ticket, uint32_t ticketBufSize, HITLS_Session **sess)
405 {
406 /* Decrypt the ticket. */
407 uint32_t plaintextLen = ticketBufSize;
408 uint8_t *plaintext = BSL_SAL_Calloc(1u, ticketBufSize);
409 if (plaintext == NULL) {
410 BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL);
411 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16037, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
412 "plaintext malloc fail when decrypt session ticket.", 0, 0, 0, 0);
413 return HITLS_MEMALLOC_FAIL;
414 }
415 int32_t ret;
416 ret = SAL_CRYPT_Decrypt(libCtx, attrName,
417 cipher, ticket->encryptedState, ticket->encryptedStateSize, plaintext, &plaintextLen);
418 if (ret != HITLS_SUCCESS) {
419 BSL_SAL_FREE(plaintext);
420 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16038, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN,
421 "SAL_CRYPT_Decrypt fail when decrypt session ticket.", 0, 0, 0, 0);
422 /* The ticket fails to be decrypted, but the complete connection can be established. Therefore, HITLS_SUCCESS is
423 * returned. */
424 return HITLS_SUCCESS;
425 }
426
427 #ifdef HITLS_TLS_SUITE_CIPHER_CBC
428 /* Padding needs to be verified in CBC mode. */
429 if (cipher->type == HITLS_CBC_CIPHER) {
430 /* The last byte is the padding length field, and the padding content is the length value. */
431 uint8_t paddingLen = plaintext[plaintextLen - 1];
432 for (uint32_t i = 1; i <= paddingLen; i++) {
433 if (plaintext[plaintextLen - 1 - i] != paddingLen) {
434 BSL_SAL_FREE(plaintext);
435 return HITLS_SUCCESS;
436 }
437 }
438 plaintextLen -= paddingLen + sizeof(uint8_t);
439 }
440 #endif
441
442 /* Parse the ticket content to the SESS. */
443 HITLS_Session *session = HITLS_SESS_New();
444 if (session == NULL) {
445 BSL_SAL_FREE(plaintext);
446 BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL);
447 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16039, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
448 "HITLS_SESS_New fail when decrypt session ticket.", 0, 0, 0, 0);
449 return HITLS_MEMALLOC_FAIL;
450 }
451 ret = SESS_Decode(session, plaintext, plaintextLen);
452 BSL_SAL_FREE(plaintext);
453 if (ret != HITLS_SUCCESS) {
454 HITLS_SESS_Free(session);
455 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16040, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN,
456 "SESS_Decode fail when decrypt session ticket.", 0, 0, 0, 0);
457 /* The ticket content fails to be parsed, but the complete connection can be established. Therefore,
458 * HITLS_SUCCESS is returned. */
459 return HITLS_SUCCESS;
460 }
461
462 *sess = session;
463 return HITLS_SUCCESS;
464 }
465
SESSMGR_DecryptSessionTicket(HITLS_Lib_Ctx * libCtx,const char * attrName,const TLS_SessionMgr * sessMgr,HITLS_Session ** sess,const uint8_t * ticketBuf,uint32_t ticketBufSize,bool * isTicketExpect)466 int32_t SESSMGR_DecryptSessionTicket(HITLS_Lib_Ctx *libCtx, const char *attrName,
467 const TLS_SessionMgr *sessMgr, HITLS_Session **sess, const uint8_t *ticketBuf,
468 uint32_t ticketBufSize, bool *isTicketExpect)
469 {
470 if (sessMgr == NULL || sess == NULL || ticketBuf == NULL || isTicketExpect == NULL) {
471 BSL_ERR_PUSH_ERROR(HITLS_INTERNAL_EXCEPTION);
472 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16041, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
473 "SESSMGR_DecryptSessionTicket input parameter is NULL.", 0, 0, 0, 0);
474 return HITLS_INTERNAL_EXCEPTION;
475 }
476
477 int32_t ret;
478 Ticket ticket = {0};
479 /* Parse the data into the ticket structure. */
480 ret = ParseSessionTicket(&ticket, ticketBuf, ticketBufSize);
481 if (ret != HITLS_SUCCESS) {
482 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16042, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN,
483 "ParseSessionTicket fail when decrypt session ticket.", 0, 0, 0, 0);
484 /* If the ticket fails to be parsed, the session is not resumption and the complete connection is established.
485 * Therefore, HITLS_SUCCESS is returned. */
486 *isTicketExpect = true;
487 return HITLS_SUCCESS;
488 }
489
490 /* Obtain decryption information. */
491 HITLS_CipherParameters cipher = {0};
492 int32_t retVal = GetSessDecryptInfo(sessMgr, &ticket, &cipher);
493 if (retVal < 0) {
494 BSL_ERR_PUSH_ERROR(HITLS_SESS_ERR_SESSION_TICKET_KEY_FAIL);
495 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16043, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
496 "GetSessDecryptInfo fail when decrypt session ticket.", 0, 0, 0, 0);
497 return HITLS_SESS_ERR_SESSION_TICKET_KEY_FAIL;
498 }
499 switch (retVal) {
500 case HITLS_TICKET_KEY_RET_FAIL:
501 /* If no corresponding key is found, the system directly returns a message and complete link establishment
502 * is performed. */
503 *isTicketExpect = true;
504 return HITLS_SUCCESS;
505 case HITLS_TICKET_KEY_RET_SUCCESS_RENEW:
506 *isTicketExpect = true;
507 break;
508 case HITLS_TICKET_KEY_RET_SUCCESS:
509 default:
510 *isTicketExpect = false;
511 break;
512 }
513 #ifdef HITLS_TLS_SUITE_CIPHER_CBC
514 /* Verify the MAC address. */
515 bool isPass = true;
516 ret = CheckTicketHmac(libCtx, attrName, &cipher, &ticket, ticketBuf, ticketBufSize, &isPass);
517 if ((ret != HITLS_SUCCESS) || (!isPass)) {
518 /* If the HMAC check fails, the session is not restored and complete link establishment is performed. */
519 return ret;
520 }
521 #endif
522 /* Parse the ticket content to the SESS. */
523 return GenerateSessFromTicket(libCtx, attrName, &cipher, &ticket, ticketBufSize, sess);
524 }
525 #endif /* HITLS_TLS_FEATURE_SESSION_TICKET */