blob: 7d07d191fd7fe8a7ea57762523333c919611b20a [file] [log] [blame]
Jens Wiklander817466c2018-05-22 13:49:31 +02001/*
2 * TLS server tickets callbacks implementation
3 *
Jerome Forissier79013242021-07-28 10:24:04 +02004 * Copyright The Mbed TLS Contributors
5 * SPDX-License-Identifier: Apache-2.0
Jens Wiklander817466c2018-05-22 13:49:31 +02006 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
Jens Wiklander817466c2018-05-22 13:49:31 +020018 */
19
Jerome Forissier79013242021-07-28 10:24:04 +020020#include "common.h"
Jens Wiklander817466c2018-05-22 13:49:31 +020021
22#if defined(MBEDTLS_SSL_TICKET_C)
23
Jens Wiklander817466c2018-05-22 13:49:31 +020024#include "mbedtls/platform.h"
Jens Wiklander817466c2018-05-22 13:49:31 +020025
Jens Wiklander32b31802023-10-06 16:59:46 +020026#include "ssl_misc.h"
Jens Wiklander817466c2018-05-22 13:49:31 +020027#include "mbedtls/ssl_ticket.h"
Jerome Forissier11fa71b2020-04-20 17:17:56 +020028#include "mbedtls/error.h"
Jens Wiklander3d3b0592019-03-20 15:30:29 +010029#include "mbedtls/platform_util.h"
Jens Wiklander817466c2018-05-22 13:49:31 +020030
31#include <string.h>
32
Jens Wiklander32b31802023-10-06 16:59:46 +020033#if defined(MBEDTLS_USE_PSA_CRYPTO)
34#define PSA_TO_MBEDTLS_ERR(status) PSA_TO_MBEDTLS_ERR_LIST(status, \
35 psa_to_ssl_errors, \
36 psa_generic_status_to_mbedtls)
37#endif
38
Jens Wiklander817466c2018-05-22 13:49:31 +020039/*
Jerome Forissier039e02d2022-08-09 17:10:15 +020040 * Initialize context
Jens Wiklander817466c2018-05-22 13:49:31 +020041 */
Jens Wiklander32b31802023-10-06 16:59:46 +020042void mbedtls_ssl_ticket_init(mbedtls_ssl_ticket_context *ctx)
Jens Wiklander817466c2018-05-22 13:49:31 +020043{
Jens Wiklander32b31802023-10-06 16:59:46 +020044 memset(ctx, 0, sizeof(mbedtls_ssl_ticket_context));
Jens Wiklander817466c2018-05-22 13:49:31 +020045
46#if defined(MBEDTLS_THREADING_C)
Jens Wiklander32b31802023-10-06 16:59:46 +020047 mbedtls_mutex_init(&ctx->mutex);
Jens Wiklander817466c2018-05-22 13:49:31 +020048#endif
49}
50
Jens Wiklander32b31802023-10-06 16:59:46 +020051#define MAX_KEY_BYTES MBEDTLS_SSL_TICKET_MAX_KEY_BYTES
Jens Wiklander817466c2018-05-22 13:49:31 +020052
Jens Wiklander32b31802023-10-06 16:59:46 +020053#define TICKET_KEY_NAME_BYTES MBEDTLS_SSL_TICKET_KEY_NAME_BYTES
Jerome Forissier11fa71b2020-04-20 17:17:56 +020054#define TICKET_IV_BYTES 12
55#define TICKET_CRYPT_LEN_BYTES 2
56#define TICKET_AUTH_TAG_BYTES 16
57
Jens Wiklander32b31802023-10-06 16:59:46 +020058#define TICKET_MIN_LEN (TICKET_KEY_NAME_BYTES + \
59 TICKET_IV_BYTES + \
60 TICKET_CRYPT_LEN_BYTES + \
61 TICKET_AUTH_TAG_BYTES)
62#define TICKET_ADD_DATA_LEN (TICKET_KEY_NAME_BYTES + \
63 TICKET_IV_BYTES + \
64 TICKET_CRYPT_LEN_BYTES)
Jerome Forissier11fa71b2020-04-20 17:17:56 +020065
Jens Wiklander817466c2018-05-22 13:49:31 +020066/*
67 * Generate/update a key
68 */
Jerome Forissier039e02d2022-08-09 17:10:15 +020069MBEDTLS_CHECK_RETURN_CRITICAL
Jens Wiklander32b31802023-10-06 16:59:46 +020070static int ssl_ticket_gen_key(mbedtls_ssl_ticket_context *ctx,
71 unsigned char index)
Jens Wiklander817466c2018-05-22 13:49:31 +020072{
Jerome Forissier11fa71b2020-04-20 17:17:56 +020073 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander32b31802023-10-06 16:59:46 +020074 unsigned char buf[MAX_KEY_BYTES] = { 0 };
Jens Wiklander817466c2018-05-22 13:49:31 +020075 mbedtls_ssl_ticket_key *key = ctx->keys + index;
76
Jens Wiklander32b31802023-10-06 16:59:46 +020077#if defined(MBEDTLS_USE_PSA_CRYPTO)
78 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Jens Wiklander817466c2018-05-22 13:49:31 +020079#endif
80
Jens Wiklander32b31802023-10-06 16:59:46 +020081#if defined(MBEDTLS_HAVE_TIME)
82 key->generation_time = mbedtls_time(NULL);
83#endif
Jens Wiklander817466c2018-05-22 13:49:31 +020084
Jens Wiklander32b31802023-10-06 16:59:46 +020085 if ((ret = ctx->f_rng(ctx->p_rng, key->name, sizeof(key->name))) != 0) {
86 return ret;
87 }
Jens Wiklander817466c2018-05-22 13:49:31 +020088
Jens Wiklander32b31802023-10-06 16:59:46 +020089 if ((ret = ctx->f_rng(ctx->p_rng, buf, sizeof(buf))) != 0) {
90 return ret;
91 }
92
93#if defined(MBEDTLS_USE_PSA_CRYPTO)
94 psa_set_key_usage_flags(&attributes,
95 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
96 psa_set_key_algorithm(&attributes, key->alg);
97 psa_set_key_type(&attributes, key->key_type);
98 psa_set_key_bits(&attributes, key->key_bits);
99
100 ret = PSA_TO_MBEDTLS_ERR(
101 psa_import_key(&attributes, buf,
102 PSA_BITS_TO_BYTES(key->key_bits),
103 &key->key));
104#else
Jens Wiklander817466c2018-05-22 13:49:31 +0200105 /* With GCM and CCM, same context can encrypt & decrypt */
Jens Wiklander32b31802023-10-06 16:59:46 +0200106 ret = mbedtls_cipher_setkey(&key->ctx, buf,
107 mbedtls_cipher_get_key_bitlen(&key->ctx),
108 MBEDTLS_ENCRYPT);
109#endif /* MBEDTLS_USE_PSA_CRYPTO */
Jens Wiklander817466c2018-05-22 13:49:31 +0200110
Jens Wiklander32b31802023-10-06 16:59:46 +0200111 mbedtls_platform_zeroize(buf, sizeof(buf));
Jens Wiklander817466c2018-05-22 13:49:31 +0200112
Jens Wiklander32b31802023-10-06 16:59:46 +0200113 return ret;
Jens Wiklander817466c2018-05-22 13:49:31 +0200114}
115
116/*
117 * Rotate/generate keys if necessary
118 */
Jerome Forissier039e02d2022-08-09 17:10:15 +0200119MBEDTLS_CHECK_RETURN_CRITICAL
Jens Wiklander32b31802023-10-06 16:59:46 +0200120static int ssl_ticket_update_keys(mbedtls_ssl_ticket_context *ctx)
Jens Wiklander817466c2018-05-22 13:49:31 +0200121{
122#if !defined(MBEDTLS_HAVE_TIME)
123 ((void) ctx);
124#else
Jens Wiklander32b31802023-10-06 16:59:46 +0200125 if (ctx->ticket_lifetime != 0) {
126 mbedtls_time_t current_time = mbedtls_time(NULL);
127 mbedtls_time_t key_time = ctx->keys[ctx->active].generation_time;
Jens Wiklander817466c2018-05-22 13:49:31 +0200128
Jens Wiklander32b31802023-10-06 16:59:46 +0200129#if defined(MBEDTLS_USE_PSA_CRYPTO)
130 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
131#endif
132
133 if (current_time >= key_time &&
134 (uint64_t) (current_time - key_time) < ctx->ticket_lifetime) {
135 return 0;
Jens Wiklander817466c2018-05-22 13:49:31 +0200136 }
137
138 ctx->active = 1 - ctx->active;
139
Jens Wiklander32b31802023-10-06 16:59:46 +0200140#if defined(MBEDTLS_USE_PSA_CRYPTO)
141 if ((status = psa_destroy_key(ctx->keys[ctx->active].key)) != PSA_SUCCESS) {
142 return PSA_TO_MBEDTLS_ERR(status);
143 }
144#endif /* MBEDTLS_USE_PSA_CRYPTO */
145
146 return ssl_ticket_gen_key(ctx, ctx->active);
147 } else
Jens Wiklander817466c2018-05-22 13:49:31 +0200148#endif /* MBEDTLS_HAVE_TIME */
Jens Wiklander32b31802023-10-06 16:59:46 +0200149 return 0;
150}
151
152/*
153 * Rotate active session ticket encryption key
154 */
155int mbedtls_ssl_ticket_rotate(mbedtls_ssl_ticket_context *ctx,
156 const unsigned char *name, size_t nlength,
157 const unsigned char *k, size_t klength,
158 uint32_t lifetime)
159{
160 const unsigned char idx = 1 - ctx->active;
161 mbedtls_ssl_ticket_key * const key = ctx->keys + idx;
162 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
163
164#if defined(MBEDTLS_USE_PSA_CRYPTO)
165 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
166 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
167 const size_t bitlen = key->key_bits;
168#else
169 const int bitlen = mbedtls_cipher_get_key_bitlen(&key->ctx);
170#endif
171
172 if (nlength < TICKET_KEY_NAME_BYTES || klength * 8 < (size_t) bitlen) {
173 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
174 }
175
176#if defined(MBEDTLS_USE_PSA_CRYPTO)
177 if ((status = psa_destroy_key(key->key)) != PSA_SUCCESS) {
178 ret = PSA_TO_MBEDTLS_ERR(status);
179 return ret;
180 }
181
182 psa_set_key_usage_flags(&attributes,
183 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
184 psa_set_key_algorithm(&attributes, key->alg);
185 psa_set_key_type(&attributes, key->key_type);
186 psa_set_key_bits(&attributes, key->key_bits);
187
188 if ((status = psa_import_key(&attributes, k,
189 PSA_BITS_TO_BYTES(key->key_bits),
190 &key->key)) != PSA_SUCCESS) {
191 ret = PSA_TO_MBEDTLS_ERR(status);
192 return ret;
193 }
194#else
195 ret = mbedtls_cipher_setkey(&key->ctx, k, bitlen, MBEDTLS_ENCRYPT);
196 if (ret != 0) {
197 return ret;
198 }
199#endif /* MBEDTLS_USE_PSA_CRYPTO */
200
201 ctx->active = idx;
202 ctx->ticket_lifetime = lifetime;
203 memcpy(key->name, name, TICKET_KEY_NAME_BYTES);
204#if defined(MBEDTLS_HAVE_TIME)
205 key->generation_time = mbedtls_time(NULL);
206#endif
207 return 0;
Jens Wiklander817466c2018-05-22 13:49:31 +0200208}
209
210/*
211 * Setup context for actual use
212 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200213int mbedtls_ssl_ticket_setup(mbedtls_ssl_ticket_context *ctx,
214 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
215 mbedtls_cipher_type_t cipher,
216 uint32_t lifetime)
Jens Wiklander817466c2018-05-22 13:49:31 +0200217{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200218 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander32b31802023-10-06 16:59:46 +0200219 size_t key_bits;
220
221#if defined(MBEDTLS_USE_PSA_CRYPTO)
222 psa_algorithm_t alg;
223 psa_key_type_t key_type;
224#else
Jens Wiklander817466c2018-05-22 13:49:31 +0200225 const mbedtls_cipher_info_t *cipher_info;
Jens Wiklander32b31802023-10-06 16:59:46 +0200226#endif /* MBEDTLS_USE_PSA_CRYPTO */
227
228#if defined(MBEDTLS_USE_PSA_CRYPTO)
229 if (mbedtls_ssl_cipher_to_psa(cipher, TICKET_AUTH_TAG_BYTES,
230 &alg, &key_type, &key_bits) != PSA_SUCCESS) {
231 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
232 }
233
234 if (PSA_ALG_IS_AEAD(alg) == 0) {
235 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
236 }
237#else
238 cipher_info = mbedtls_cipher_info_from_type(cipher);
239
240 if (mbedtls_cipher_info_get_mode(cipher_info) != MBEDTLS_MODE_GCM &&
241 mbedtls_cipher_info_get_mode(cipher_info) != MBEDTLS_MODE_CCM &&
242 mbedtls_cipher_info_get_mode(cipher_info) != MBEDTLS_MODE_CHACHAPOLY) {
243 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
244 }
245
246 key_bits = mbedtls_cipher_info_get_key_bitlen(cipher_info);
247#endif /* MBEDTLS_USE_PSA_CRYPTO */
248
249 if (key_bits > 8 * MAX_KEY_BYTES) {
250 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
251 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200252
253 ctx->f_rng = f_rng;
254 ctx->p_rng = p_rng;
255
256 ctx->ticket_lifetime = lifetime;
257
Jens Wiklander32b31802023-10-06 16:59:46 +0200258#if defined(MBEDTLS_USE_PSA_CRYPTO)
259 ctx->keys[0].alg = alg;
260 ctx->keys[0].key_type = key_type;
261 ctx->keys[0].key_bits = key_bits;
Jens Wiklander817466c2018-05-22 13:49:31 +0200262
Jens Wiklander32b31802023-10-06 16:59:46 +0200263 ctx->keys[1].alg = alg;
264 ctx->keys[1].key_type = key_type;
265 ctx->keys[1].key_bits = key_bits;
266#else
267 if ((ret = mbedtls_cipher_setup(&ctx->keys[0].ctx, cipher_info)) != 0) {
268 return ret;
Jens Wiklander817466c2018-05-22 13:49:31 +0200269 }
270
Jens Wiklander32b31802023-10-06 16:59:46 +0200271 if ((ret = mbedtls_cipher_setup(&ctx->keys[1].ctx, cipher_info)) != 0) {
272 return ret;
273 }
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200274#endif /* MBEDTLS_USE_PSA_CRYPTO */
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200275
Jens Wiklander32b31802023-10-06 16:59:46 +0200276 if ((ret = ssl_ticket_gen_key(ctx, 0)) != 0 ||
277 (ret = ssl_ticket_gen_key(ctx, 1)) != 0) {
278 return ret;
Jens Wiklander817466c2018-05-22 13:49:31 +0200279 }
280
Jens Wiklander32b31802023-10-06 16:59:46 +0200281 return 0;
Jens Wiklander817466c2018-05-22 13:49:31 +0200282}
283
284/*
Jens Wiklander817466c2018-05-22 13:49:31 +0200285 * Create session ticket, with the following structure:
286 *
287 * struct {
288 * opaque key_name[4];
289 * opaque iv[12];
290 * opaque encrypted_state<0..2^16-1>;
291 * opaque tag[16];
292 * } ticket;
293 *
294 * The key_name, iv, and length of encrypted_state are the additional
295 * authenticated data.
296 */
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200297
Jens Wiklander32b31802023-10-06 16:59:46 +0200298int mbedtls_ssl_ticket_write(void *p_ticket,
299 const mbedtls_ssl_session *session,
300 unsigned char *start,
301 const unsigned char *end,
302 size_t *tlen,
303 uint32_t *ticket_lifetime)
Jens Wiklander817466c2018-05-22 13:49:31 +0200304{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200305 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +0200306 mbedtls_ssl_ticket_context *ctx = p_ticket;
307 mbedtls_ssl_ticket_key *key;
308 unsigned char *key_name = start;
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200309 unsigned char *iv = start + TICKET_KEY_NAME_BYTES;
310 unsigned char *state_len_bytes = iv + TICKET_IV_BYTES;
311 unsigned char *state = state_len_bytes + TICKET_CRYPT_LEN_BYTES;
Jens Wiklander817466c2018-05-22 13:49:31 +0200312 size_t clear_len, ciph_len;
313
Jens Wiklander32b31802023-10-06 16:59:46 +0200314#if defined(MBEDTLS_USE_PSA_CRYPTO)
315 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
316#endif
317
Jens Wiklander817466c2018-05-22 13:49:31 +0200318 *tlen = 0;
319
Jens Wiklander32b31802023-10-06 16:59:46 +0200320 if (ctx == NULL || ctx->f_rng == NULL) {
321 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
322 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200323
324 /* We need at least 4 bytes for key_name, 12 for IV, 2 for len 16 for tag,
325 * in addition to session itself, that will be checked when writing it. */
Jens Wiklander32b31802023-10-06 16:59:46 +0200326 MBEDTLS_SSL_CHK_BUF_PTR(start, end, TICKET_MIN_LEN);
Jens Wiklander817466c2018-05-22 13:49:31 +0200327
328#if defined(MBEDTLS_THREADING_C)
Jens Wiklander32b31802023-10-06 16:59:46 +0200329 if ((ret = mbedtls_mutex_lock(&ctx->mutex)) != 0) {
330 return ret;
331 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200332#endif
333
Jens Wiklander32b31802023-10-06 16:59:46 +0200334 if ((ret = ssl_ticket_update_keys(ctx)) != 0) {
Jens Wiklander817466c2018-05-22 13:49:31 +0200335 goto cleanup;
Jens Wiklander32b31802023-10-06 16:59:46 +0200336 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200337
338 key = &ctx->keys[ctx->active];
339
340 *ticket_lifetime = ctx->ticket_lifetime;
341
Jens Wiklander32b31802023-10-06 16:59:46 +0200342 memcpy(key_name, key->name, TICKET_KEY_NAME_BYTES);
Jens Wiklander817466c2018-05-22 13:49:31 +0200343
Jens Wiklander32b31802023-10-06 16:59:46 +0200344 if ((ret = ctx->f_rng(ctx->p_rng, iv, TICKET_IV_BYTES)) != 0) {
Jens Wiklander817466c2018-05-22 13:49:31 +0200345 goto cleanup;
Jens Wiklander32b31802023-10-06 16:59:46 +0200346 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200347
348 /* Dump session state */
Jens Wiklander32b31802023-10-06 16:59:46 +0200349 if ((ret = mbedtls_ssl_session_save(session,
350 state, end - state,
351 &clear_len)) != 0 ||
352 (unsigned long) clear_len > 65535) {
Jens Wiklander817466c2018-05-22 13:49:31 +0200353 goto cleanup;
354 }
Jens Wiklander32b31802023-10-06 16:59:46 +0200355 MBEDTLS_PUT_UINT16_BE(clear_len, state_len_bytes, 0);
356
357 /* Encrypt and authenticate */
358#if defined(MBEDTLS_USE_PSA_CRYPTO)
359 if ((status = psa_aead_encrypt(key->key, key->alg, iv, TICKET_IV_BYTES,
360 key_name, TICKET_ADD_DATA_LEN,
361 state, clear_len,
362 state, end - state,
363 &ciph_len)) != PSA_SUCCESS) {
364 ret = PSA_TO_MBEDTLS_ERR(status);
365 goto cleanup;
366 }
367#else
368 if ((ret = mbedtls_cipher_auth_encrypt_ext(&key->ctx,
369 iv, TICKET_IV_BYTES,
370 /* Additional data: key name, IV and length */
371 key_name, TICKET_ADD_DATA_LEN,
372 state, clear_len,
373 state, end - state, &ciph_len,
374 TICKET_AUTH_TAG_BYTES)) != 0) {
375 goto cleanup;
376 }
377#endif /* MBEDTLS_USE_PSA_CRYPTO */
378
379 if (ciph_len != clear_len + TICKET_AUTH_TAG_BYTES) {
Jens Wiklander817466c2018-05-22 13:49:31 +0200380 ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR;
381 goto cleanup;
382 }
383
Jerome Forissier79013242021-07-28 10:24:04 +0200384 *tlen = TICKET_MIN_LEN + ciph_len - TICKET_AUTH_TAG_BYTES;
Jens Wiklander817466c2018-05-22 13:49:31 +0200385
386cleanup:
387#if defined(MBEDTLS_THREADING_C)
Jens Wiklander32b31802023-10-06 16:59:46 +0200388 if (mbedtls_mutex_unlock(&ctx->mutex) != 0) {
389 return MBEDTLS_ERR_THREADING_MUTEX_ERROR;
390 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200391#endif
392
Jens Wiklander32b31802023-10-06 16:59:46 +0200393 return ret;
Jens Wiklander817466c2018-05-22 13:49:31 +0200394}
395
396/*
397 * Select key based on name
398 */
399static mbedtls_ssl_ticket_key *ssl_ticket_select_key(
Jens Wiklander32b31802023-10-06 16:59:46 +0200400 mbedtls_ssl_ticket_context *ctx,
401 const unsigned char name[4])
Jens Wiklander817466c2018-05-22 13:49:31 +0200402{
403 unsigned char i;
404
Jens Wiklander32b31802023-10-06 16:59:46 +0200405 for (i = 0; i < sizeof(ctx->keys) / sizeof(*ctx->keys); i++) {
406 if (memcmp(name, ctx->keys[i].name, 4) == 0) {
407 return &ctx->keys[i];
408 }
409 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200410
Jens Wiklander32b31802023-10-06 16:59:46 +0200411 return NULL;
Jens Wiklander817466c2018-05-22 13:49:31 +0200412}
413
414/*
415 * Load session ticket (see mbedtls_ssl_ticket_write for structure)
416 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200417int mbedtls_ssl_ticket_parse(void *p_ticket,
418 mbedtls_ssl_session *session,
419 unsigned char *buf,
420 size_t len)
Jens Wiklander817466c2018-05-22 13:49:31 +0200421{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200422 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +0200423 mbedtls_ssl_ticket_context *ctx = p_ticket;
424 mbedtls_ssl_ticket_key *key;
425 unsigned char *key_name = buf;
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200426 unsigned char *iv = buf + TICKET_KEY_NAME_BYTES;
427 unsigned char *enc_len_p = iv + TICKET_IV_BYTES;
428 unsigned char *ticket = enc_len_p + TICKET_CRYPT_LEN_BYTES;
Jens Wiklander817466c2018-05-22 13:49:31 +0200429 size_t enc_len, clear_len;
430
Jens Wiklander32b31802023-10-06 16:59:46 +0200431#if defined(MBEDTLS_USE_PSA_CRYPTO)
432 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +0200433#endif
434
Jens Wiklander32b31802023-10-06 16:59:46 +0200435 if (ctx == NULL || ctx->f_rng == NULL) {
436 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
437 }
438
439 if (len < TICKET_MIN_LEN) {
440 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
441 }
442
443#if defined(MBEDTLS_THREADING_C)
444 if ((ret = mbedtls_mutex_lock(&ctx->mutex)) != 0) {
445 return ret;
446 }
447#endif
448
449 if ((ret = ssl_ticket_update_keys(ctx)) != 0) {
Jens Wiklander817466c2018-05-22 13:49:31 +0200450 goto cleanup;
Jens Wiklander32b31802023-10-06 16:59:46 +0200451 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200452
Jens Wiklander32b31802023-10-06 16:59:46 +0200453 enc_len = (enc_len_p[0] << 8) | enc_len_p[1];
Jens Wiklander817466c2018-05-22 13:49:31 +0200454
Jens Wiklander32b31802023-10-06 16:59:46 +0200455 if (len != TICKET_MIN_LEN + enc_len) {
Jens Wiklander817466c2018-05-22 13:49:31 +0200456 ret = MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
457 goto cleanup;
458 }
459
460 /* Select key */
Jens Wiklander32b31802023-10-06 16:59:46 +0200461 if ((key = ssl_ticket_select_key(ctx, key_name)) == NULL) {
Jens Wiklander817466c2018-05-22 13:49:31 +0200462 /* We can't know for sure but this is a likely option unless we're
463 * under attack - this is only informative anyway */
464 ret = MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED;
465 goto cleanup;
466 }
467
468 /* Decrypt and authenticate */
Jens Wiklander32b31802023-10-06 16:59:46 +0200469#if defined(MBEDTLS_USE_PSA_CRYPTO)
470 if ((status = psa_aead_decrypt(key->key, key->alg, iv, TICKET_IV_BYTES,
471 key_name, TICKET_ADD_DATA_LEN,
472 ticket, enc_len + TICKET_AUTH_TAG_BYTES,
473 ticket, enc_len, &clear_len)) != PSA_SUCCESS) {
474 ret = PSA_TO_MBEDTLS_ERR(status);
475 goto cleanup;
476 }
477#else
478 if ((ret = mbedtls_cipher_auth_decrypt_ext(&key->ctx,
479 iv, TICKET_IV_BYTES,
480 /* Additional data: key name, IV and length */
481 key_name, TICKET_ADD_DATA_LEN,
482 ticket, enc_len + TICKET_AUTH_TAG_BYTES,
483 ticket, enc_len, &clear_len,
484 TICKET_AUTH_TAG_BYTES)) != 0) {
485 if (ret == MBEDTLS_ERR_CIPHER_AUTH_FAILED) {
Jens Wiklander817466c2018-05-22 13:49:31 +0200486 ret = MBEDTLS_ERR_SSL_INVALID_MAC;
Jens Wiklander32b31802023-10-06 16:59:46 +0200487 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200488
489 goto cleanup;
490 }
Jens Wiklander32b31802023-10-06 16:59:46 +0200491#endif /* MBEDTLS_USE_PSA_CRYPTO */
492
493 if (clear_len != enc_len) {
Jens Wiklander817466c2018-05-22 13:49:31 +0200494 ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR;
495 goto cleanup;
496 }
497
498 /* Actually load session */
Jens Wiklander32b31802023-10-06 16:59:46 +0200499 if ((ret = mbedtls_ssl_session_load(session, ticket, clear_len)) != 0) {
Jens Wiklander817466c2018-05-22 13:49:31 +0200500 goto cleanup;
Jens Wiklander32b31802023-10-06 16:59:46 +0200501 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200502
503#if defined(MBEDTLS_HAVE_TIME)
504 {
505 /* Check for expiration */
Jens Wiklander32b31802023-10-06 16:59:46 +0200506 mbedtls_time_t current_time = mbedtls_time(NULL);
Jens Wiklander817466c2018-05-22 13:49:31 +0200507
Jens Wiklander32b31802023-10-06 16:59:46 +0200508 if (current_time < session->start ||
509 (uint32_t) (current_time - session->start) > ctx->ticket_lifetime) {
Jens Wiklander817466c2018-05-22 13:49:31 +0200510 ret = MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED;
511 goto cleanup;
512 }
513 }
514#endif
515
516cleanup:
517#if defined(MBEDTLS_THREADING_C)
Jens Wiklander32b31802023-10-06 16:59:46 +0200518 if (mbedtls_mutex_unlock(&ctx->mutex) != 0) {
519 return MBEDTLS_ERR_THREADING_MUTEX_ERROR;
520 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200521#endif
522
Jens Wiklander32b31802023-10-06 16:59:46 +0200523 return ret;
Jens Wiklander817466c2018-05-22 13:49:31 +0200524}
525
526/*
527 * Free context
528 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200529void mbedtls_ssl_ticket_free(mbedtls_ssl_ticket_context *ctx)
Jens Wiklander817466c2018-05-22 13:49:31 +0200530{
Jens Wiklander32b31802023-10-06 16:59:46 +0200531#if defined(MBEDTLS_USE_PSA_CRYPTO)
532 psa_destroy_key(ctx->keys[0].key);
533 psa_destroy_key(ctx->keys[1].key);
534#else
535 mbedtls_cipher_free(&ctx->keys[0].ctx);
536 mbedtls_cipher_free(&ctx->keys[1].ctx);
537#endif /* MBEDTLS_USE_PSA_CRYPTO */
Jens Wiklander817466c2018-05-22 13:49:31 +0200538
539#if defined(MBEDTLS_THREADING_C)
Jens Wiklander32b31802023-10-06 16:59:46 +0200540 mbedtls_mutex_free(&ctx->mutex);
Jens Wiklander817466c2018-05-22 13:49:31 +0200541#endif
542
Jens Wiklander32b31802023-10-06 16:59:46 +0200543 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_ssl_ticket_context));
Jens Wiklander817466c2018-05-22 13:49:31 +0200544}
545
546#endif /* MBEDTLS_SSL_TICKET_C */