blob: 0e374671ce843850381070a5c9300412e57dbed5 [file] [log] [blame]
Manuel Pégourié-Gonnard232edd42014-07-23 16:56:27 +02001/*
2 * DTLS cookie callbacks implementation
3 *
Bence Szépkúti1e148272020-08-07 13:07:28 +02004 * Copyright The Mbed TLS Contributors
Dave Rodgman16799db2023-11-02 19:47:20 +00005 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
Manuel Pégourié-Gonnard232edd42014-07-23 16:56:27 +02006 */
7/*
8 * These session callbacks use a simple chained list
9 * to store and retrieve the session information.
10 */
11
Harry Ramsey0f6bc412024-10-04 10:36:54 +010012#include "ssl_misc.h"
Manuel Pégourié-Gonnard232edd42014-07-23 16:56:27 +020013
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020014#if defined(MBEDTLS_SSL_COOKIE_C)
Manuel Pégourié-Gonnard232edd42014-07-23 16:56:27 +020015
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000016#include "mbedtls/platform.h"
Manuel Pégourié-Gonnard232edd42014-07-23 16:56:27 +020017
SimonBd5800b72016-04-26 07:43:27 +010018#include "mbedtls/ssl_cookie.h"
Janos Follath73c616b2019-12-18 15:07:04 +000019#include "mbedtls/error.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050020#include "mbedtls/platform_util.h"
Gabor Mezei765862c2021-10-19 12:22:25 +020021#include "mbedtls/constant_time.h"
SimonBd5800b72016-04-26 07:43:27 +010022
Manuel Pégourié-Gonnardd901d172015-02-16 18:37:53 +000023#include <string.h>
24
Andrzej Kurek8a045ce2022-12-23 11:00:06 -050025#if defined(MBEDTLS_USE_PSA_CRYPTO)
Valerio Setti384fbde2024-01-02 13:26:40 +010026#include "mbedtls/psa_util.h"
Andrzej Kurek00644842023-05-30 05:45:00 -040027/* Define a local translating function to save code size by not using too many
28 * arguments in each translating place. */
29static int local_err_translation(psa_status_t status)
30{
31 return psa_status_to_mbedtls(status, psa_to_ssl_errors,
Andrzej Kurek1e4a0302023-05-30 09:45:17 -040032 ARRAY_LENGTH(psa_to_ssl_errors),
Andrzej Kurek00644842023-05-30 05:45:00 -040033 psa_generic_status_to_mbedtls);
34}
35#define PSA_TO_MBEDTLS_ERR(status) local_err_translation(status)
Andrzej Kurek8a045ce2022-12-23 11:00:06 -050036#endif
37
Manuel Pégourié-Gonnard232edd42014-07-23 16:56:27 +020038/*
Valerio Setti543d00e2022-12-22 14:27:34 +010039 * If DTLS is in use, then at least one of SHA-256 or SHA-384 is
40 * available. Try SHA-256 first as 384 wastes resources
Manuel Pégourié-Gonnard232edd42014-07-23 16:56:27 +020041 */
Elena Uziunaite0916cd72024-05-23 17:01:07 +010042#if defined(PSA_WANT_ALG_SHA_256)
Valerio Setti543d00e2022-12-22 14:27:34 +010043#define COOKIE_MD MBEDTLS_MD_SHA256
Manuel Pégourié-Gonnarde9030812014-07-23 21:29:11 +020044#define COOKIE_MD_OUTLEN 32
45#define COOKIE_HMAC_LEN 28
Elena Uziunaiteb476d4b2024-05-23 15:33:41 +010046#elif defined(PSA_WANT_ALG_SHA_384)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020047#define COOKIE_MD MBEDTLS_MD_SHA384
Manuel Pégourié-Gonnarde9030812014-07-23 21:29:11 +020048#define COOKIE_MD_OUTLEN 48
49#define COOKIE_HMAC_LEN 28
Manuel Pégourié-Gonnard232edd42014-07-23 16:56:27 +020050#else
Valerio Setti543d00e2022-12-22 14:27:34 +010051#error "DTLS hello verify needs SHA-256 or SHA-384"
Manuel Pégourié-Gonnard232edd42014-07-23 16:56:27 +020052#endif
53
Manuel Pégourié-Gonnarde9030812014-07-23 21:29:11 +020054/*
55 * Cookies are formed of a 4-bytes timestamp (or serial number) and
Shaun Case8b0ecbc2021-12-20 21:14:10 -080056 * an HMAC of timestamp and client ID.
Manuel Pégourié-Gonnarde9030812014-07-23 21:29:11 +020057 */
Gilles Peskine449bd832023-01-11 14:50:10 +010058#define COOKIE_LEN (4 + COOKIE_HMAC_LEN)
Manuel Pégourié-Gonnarde9030812014-07-23 21:29:11 +020059
Gilles Peskine449bd832023-01-11 14:50:10 +010060void mbedtls_ssl_cookie_init(mbedtls_ssl_cookie_ctx *ctx)
Manuel Pégourié-Gonnard232edd42014-07-23 16:56:27 +020061{
Neil Armstrongbca99ee2022-03-04 10:20:20 +010062#if defined(MBEDTLS_USE_PSA_CRYPTO)
Neil Armstrong488a40e2022-03-22 10:41:38 +010063 ctx->psa_hmac_key = MBEDTLS_SVC_KEY_ID_INIT;
Neil Armstrong77b69ab2022-03-04 14:35:13 +010064#else
Gilles Peskine449bd832023-01-11 14:50:10 +010065 mbedtls_md_init(&ctx->hmac_ctx);
Neil Armstrong77b69ab2022-03-04 14:35:13 +010066#endif /* MBEDTLS_USE_PSA_CRYPTO */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020067#if !defined(MBEDTLS_HAVE_TIME)
Manuel Pégourié-Gonnarde9030812014-07-23 21:29:11 +020068 ctx->serial = 0;
69#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020070 ctx->timeout = MBEDTLS_SSL_COOKIE_TIMEOUT;
Manuel Pégourié-Gonnard2a84dfd2015-05-28 15:48:09 +020071
Neil Armstrong7cd02702022-03-04 15:08:43 +010072#if !defined(MBEDTLS_USE_PSA_CRYPTO)
Manuel Pégourié-Gonnard2a84dfd2015-05-28 15:48:09 +020073#if defined(MBEDTLS_THREADING_C)
Gilles Peskine449bd832023-01-11 14:50:10 +010074 mbedtls_mutex_init(&ctx->mutex);
Manuel Pégourié-Gonnard2a84dfd2015-05-28 15:48:09 +020075#endif
Neil Armstrong7cd02702022-03-04 15:08:43 +010076#endif /* !MBEDTLS_USE_PSA_CRYPTO */
Manuel Pégourié-Gonnardbef8f092014-07-23 23:40:29 +020077}
78
Gilles Peskine449bd832023-01-11 14:50:10 +010079void mbedtls_ssl_cookie_set_timeout(mbedtls_ssl_cookie_ctx *ctx, unsigned long delay)
Manuel Pégourié-Gonnardbef8f092014-07-23 23:40:29 +020080{
81 ctx->timeout = delay;
Manuel Pégourié-Gonnard232edd42014-07-23 16:56:27 +020082}
83
Gilles Peskine449bd832023-01-11 14:50:10 +010084void mbedtls_ssl_cookie_free(mbedtls_ssl_cookie_ctx *ctx)
Manuel Pégourié-Gonnard232edd42014-07-23 16:56:27 +020085{
Troy-Butler9ac3e232024-03-22 14:46:04 -040086 if (ctx == NULL) {
87 return;
88 }
89
Neil Armstrongbca99ee2022-03-04 10:20:20 +010090#if defined(MBEDTLS_USE_PSA_CRYPTO)
Gilles Peskine449bd832023-01-11 14:50:10 +010091 psa_destroy_key(ctx->psa_hmac_key);
Neil Armstrong77b69ab2022-03-04 14:35:13 +010092#else
Gilles Peskine449bd832023-01-11 14:50:10 +010093 mbedtls_md_free(&ctx->hmac_ctx);
Manuel Pégourié-Gonnard2a84dfd2015-05-28 15:48:09 +020094
95#if defined(MBEDTLS_THREADING_C)
Gilles Peskine449bd832023-01-11 14:50:10 +010096 mbedtls_mutex_free(&ctx->mutex);
Manuel Pégourié-Gonnard2a84dfd2015-05-28 15:48:09 +020097#endif
Neil Armstrong7cd02702022-03-04 15:08:43 +010098#endif /* MBEDTLS_USE_PSA_CRYPTO */
Manuel Pégourié-Gonnard2a84dfd2015-05-28 15:48:09 +020099
Gilles Peskine449bd832023-01-11 14:50:10 +0100100 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_ssl_cookie_ctx));
Manuel Pégourié-Gonnard232edd42014-07-23 16:56:27 +0200101}
102
Gilles Peskine449bd832023-01-11 14:50:10 +0100103int mbedtls_ssl_cookie_setup(mbedtls_ssl_cookie_ctx *ctx,
104 int (*f_rng)(void *, unsigned char *, size_t),
105 void *p_rng)
Manuel Pégourié-Gonnard232edd42014-07-23 16:56:27 +0200106{
Neil Armstrongd6332012022-03-04 10:26:16 +0100107#if defined(MBEDTLS_USE_PSA_CRYPTO)
108 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
109 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
110 psa_algorithm_t alg;
Manuel Pégourié-Gonnard232edd42014-07-23 16:56:27 +0200111
Gilles Peskine449bd832023-01-11 14:50:10 +0100112 (void) f_rng;
113 (void) p_rng;
Manuel Pégourié-Gonnard232edd42014-07-23 16:56:27 +0200114
Manuel Pégourié-Gonnard2d6d9932023-03-28 11:38:08 +0200115 alg = mbedtls_md_psa_alg_from_type(COOKIE_MD);
Gilles Peskine449bd832023-01-11 14:50:10 +0100116 if (alg == 0) {
117 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
118 }
Neil Armstrongd6332012022-03-04 10:26:16 +0100119
Gilles Peskine449bd832023-01-11 14:50:10 +0100120 ctx->psa_hmac_alg = PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(alg),
121 COOKIE_HMAC_LEN);
Neil Armstrongd6332012022-03-04 10:26:16 +0100122
Gilles Peskine449bd832023-01-11 14:50:10 +0100123 psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_VERIFY_MESSAGE |
124 PSA_KEY_USAGE_SIGN_MESSAGE);
125 psa_set_key_algorithm(&attributes, ctx->psa_hmac_alg);
126 psa_set_key_type(&attributes, PSA_KEY_TYPE_HMAC);
127 psa_set_key_bits(&attributes, PSA_BYTES_TO_BITS(COOKIE_MD_OUTLEN));
Neil Armstrongd6332012022-03-04 10:26:16 +0100128
Gilles Peskine449bd832023-01-11 14:50:10 +0100129 if ((status = psa_generate_key(&attributes,
130 &ctx->psa_hmac_key)) != PSA_SUCCESS) {
Andrzej Kurek8a045ce2022-12-23 11:00:06 -0500131 return PSA_TO_MBEDTLS_ERR(status);
Neil Armstrongd6332012022-03-04 10:26:16 +0100132 }
Neil Armstrong23d34ce2022-03-04 10:32:26 +0100133#else
Neil Armstrong2217d6f2022-03-04 15:00:22 +0100134 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
135 unsigned char key[COOKIE_MD_OUTLEN];
136
Gilles Peskine449bd832023-01-11 14:50:10 +0100137 if ((ret = f_rng(p_rng, key, sizeof(key))) != 0) {
138 return ret;
139 }
Neil Armstrong2217d6f2022-03-04 15:00:22 +0100140
Gilles Peskine449bd832023-01-11 14:50:10 +0100141 ret = mbedtls_md_setup(&ctx->hmac_ctx, mbedtls_md_info_from_type(COOKIE_MD), 1);
142 if (ret != 0) {
143 return ret;
144 }
Manuel Pégourié-Gonnard232edd42014-07-23 16:56:27 +0200145
Gilles Peskine449bd832023-01-11 14:50:10 +0100146 ret = mbedtls_md_hmac_starts(&ctx->hmac_ctx, key, sizeof(key));
147 if (ret != 0) {
148 return ret;
149 }
Manuel Pégourié-Gonnard232edd42014-07-23 16:56:27 +0200150
Gilles Peskine449bd832023-01-11 14:50:10 +0100151 mbedtls_platform_zeroize(key, sizeof(key));
Neil Armstrong2217d6f2022-03-04 15:00:22 +0100152#endif /* MBEDTLS_USE_PSA_CRYPTO */
Manuel Pégourié-Gonnard232edd42014-07-23 16:56:27 +0200153
Gilles Peskine449bd832023-01-11 14:50:10 +0100154 return 0;
Manuel Pégourié-Gonnard232edd42014-07-23 16:56:27 +0200155}
156
Neil Armstrong2d5e3432022-03-21 11:39:52 +0100157#if !defined(MBEDTLS_USE_PSA_CRYPTO)
Manuel Pégourié-Gonnard232edd42014-07-23 16:56:27 +0200158/*
Manuel Pégourié-Gonnarde9030812014-07-23 21:29:11 +0200159 * Generate the HMAC part of a cookie
160 */
Manuel Pégourié-Gonnarda3115dc2022-06-17 10:52:54 +0200161MBEDTLS_CHECK_RETURN_CRITICAL
Gilles Peskine449bd832023-01-11 14:50:10 +0100162static int ssl_cookie_hmac(mbedtls_md_context_t *hmac_ctx,
163 const unsigned char time[4],
164 unsigned char **p, unsigned char *end,
165 const unsigned char *cli_id, size_t cli_id_len)
Manuel Pégourié-Gonnarde9030812014-07-23 21:29:11 +0200166{
Manuel Pégourié-Gonnarde9030812014-07-23 21:29:11 +0200167 unsigned char hmac_out[COOKIE_MD_OUTLEN];
168
Gilles Peskine449bd832023-01-11 14:50:10 +0100169 MBEDTLS_SSL_CHK_BUF_PTR(*p, end, COOKIE_HMAC_LEN);
Manuel Pégourié-Gonnarde9030812014-07-23 21:29:11 +0200170
Gilles Peskine449bd832023-01-11 14:50:10 +0100171 if (mbedtls_md_hmac_reset(hmac_ctx) != 0 ||
172 mbedtls_md_hmac_update(hmac_ctx, time, 4) != 0 ||
173 mbedtls_md_hmac_update(hmac_ctx, cli_id, cli_id_len) != 0 ||
174 mbedtls_md_hmac_finish(hmac_ctx, hmac_out) != 0) {
175 return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
Manuel Pégourié-Gonnarde9030812014-07-23 21:29:11 +0200176 }
177
Gilles Peskine449bd832023-01-11 14:50:10 +0100178 memcpy(*p, hmac_out, COOKIE_HMAC_LEN);
Manuel Pégourié-Gonnarde9030812014-07-23 21:29:11 +0200179 *p += COOKIE_HMAC_LEN;
180
Gilles Peskine449bd832023-01-11 14:50:10 +0100181 return 0;
Manuel Pégourié-Gonnarde9030812014-07-23 21:29:11 +0200182}
Neil Armstrong2d5e3432022-03-21 11:39:52 +0100183#endif /* !MBEDTLS_USE_PSA_CRYPTO */
Manuel Pégourié-Gonnarde9030812014-07-23 21:29:11 +0200184
185/*
Manuel Pégourié-Gonnard232edd42014-07-23 16:56:27 +0200186 * Generate cookie for DTLS ClientHello verification
187 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100188int mbedtls_ssl_cookie_write(void *p_ctx,
189 unsigned char **p, unsigned char *end,
190 const unsigned char *cli_id, size_t cli_id_len)
Manuel Pégourié-Gonnard232edd42014-07-23 16:56:27 +0200191{
Neil Armstrong2d5e3432022-03-21 11:39:52 +0100192#if defined(MBEDTLS_USE_PSA_CRYPTO)
193 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Neil Armstrong79daea22022-03-21 12:05:51 +0100194 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Neil Armstrong2d5e3432022-03-21 11:39:52 +0100195 size_t sign_mac_length = 0;
196#endif
Janos Follath865b3eb2019-12-16 11:46:15 +0000197 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200198 mbedtls_ssl_cookie_ctx *ctx = (mbedtls_ssl_cookie_ctx *) p_ctx;
Manuel Pégourié-Gonnarde9030812014-07-23 21:29:11 +0200199 unsigned long t;
Manuel Pégourié-Gonnarde4de0612014-07-23 17:26:48 +0200200
Gilles Peskine449bd832023-01-11 14:50:10 +0100201 if (ctx == NULL || cli_id == NULL) {
202 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
203 }
Manuel Pégourié-Gonnard232edd42014-07-23 16:56:27 +0200204
Gilles Peskine449bd832023-01-11 14:50:10 +0100205 MBEDTLS_SSL_CHK_BUF_PTR(*p, end, COOKIE_LEN);
Manuel Pégourié-Gonnard232edd42014-07-23 16:56:27 +0200206
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200207#if defined(MBEDTLS_HAVE_TIME)
Gilles Peskine449bd832023-01-11 14:50:10 +0100208 t = (unsigned long) mbedtls_time(NULL);
Manuel Pégourié-Gonnarde9030812014-07-23 21:29:11 +0200209#else
210 t = ctx->serial++;
211#endif
Manuel Pégourié-Gonnard232edd42014-07-23 16:56:27 +0200212
Joe Subbianib6511b02021-07-16 15:02:55 +0100213 MBEDTLS_PUT_UINT32_BE(t, *p, 0);
Manuel Pégourié-Gonnarde9030812014-07-23 21:29:11 +0200214 *p += 4;
Manuel Pégourié-Gonnard232edd42014-07-23 16:56:27 +0200215
Neil Armstrong7cd02702022-03-04 15:08:43 +0100216#if defined(MBEDTLS_USE_PSA_CRYPTO)
Gilles Peskine449bd832023-01-11 14:50:10 +0100217 status = psa_mac_sign_setup(&operation, ctx->psa_hmac_key,
218 ctx->psa_hmac_alg);
219 if (status != PSA_SUCCESS) {
Andrzej Kurek8a045ce2022-12-23 11:00:06 -0500220 ret = PSA_TO_MBEDTLS_ERR(status);
Neil Armstrong2d5e3432022-03-21 11:39:52 +0100221 goto exit;
222 }
223
Gilles Peskine449bd832023-01-11 14:50:10 +0100224 status = psa_mac_update(&operation, *p - 4, 4);
225 if (status != PSA_SUCCESS) {
Andrzej Kurek8a045ce2022-12-23 11:00:06 -0500226 ret = PSA_TO_MBEDTLS_ERR(status);
Neil Armstrong2d5e3432022-03-21 11:39:52 +0100227 goto exit;
228 }
229
Gilles Peskine449bd832023-01-11 14:50:10 +0100230 status = psa_mac_update(&operation, cli_id, cli_id_len);
231 if (status != PSA_SUCCESS) {
Andrzej Kurek8a045ce2022-12-23 11:00:06 -0500232 ret = PSA_TO_MBEDTLS_ERR(status);
Neil Armstrong2d5e3432022-03-21 11:39:52 +0100233 goto exit;
234 }
235
Gilles Peskine449bd832023-01-11 14:50:10 +0100236 status = psa_mac_sign_finish(&operation, *p, COOKIE_MD_OUTLEN,
237 &sign_mac_length);
238 if (status != PSA_SUCCESS) {
Andrzej Kurek8a045ce2022-12-23 11:00:06 -0500239 ret = PSA_TO_MBEDTLS_ERR(status);
Neil Armstrong2d5e3432022-03-21 11:39:52 +0100240 goto exit;
241 }
242
243 *p += COOKIE_HMAC_LEN;
244
245 ret = 0;
Neil Armstrong7cd02702022-03-04 15:08:43 +0100246#else
Manuel Pégourié-Gonnard2a84dfd2015-05-28 15:48:09 +0200247#if defined(MBEDTLS_THREADING_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100248 if ((ret = mbedtls_mutex_lock(&ctx->mutex)) != 0) {
249 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_SSL_INTERNAL_ERROR, ret);
250 }
Manuel Pégourié-Gonnard2a84dfd2015-05-28 15:48:09 +0200251#endif
252
Gilles Peskine449bd832023-01-11 14:50:10 +0100253 ret = ssl_cookie_hmac(&ctx->hmac_ctx, *p - 4,
254 p, end, cli_id, cli_id_len);
Manuel Pégourié-Gonnard2a84dfd2015-05-28 15:48:09 +0200255
256#if defined(MBEDTLS_THREADING_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100257 if (mbedtls_mutex_unlock(&ctx->mutex) != 0) {
258 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_SSL_INTERNAL_ERROR,
259 MBEDTLS_ERR_THREADING_MUTEX_ERROR);
260 }
Manuel Pégourié-Gonnard2a84dfd2015-05-28 15:48:09 +0200261#endif
Neil Armstrong7cd02702022-03-04 15:08:43 +0100262#endif /* MBEDTLS_USE_PSA_CRYPTO */
Manuel Pégourié-Gonnard2a84dfd2015-05-28 15:48:09 +0200263
Neil Armstrong2d5e3432022-03-21 11:39:52 +0100264#if defined(MBEDTLS_USE_PSA_CRYPTO)
265exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100266 status = psa_mac_abort(&operation);
267 if (status != PSA_SUCCESS) {
Andrzej Kurek8a045ce2022-12-23 11:00:06 -0500268 ret = PSA_TO_MBEDTLS_ERR(status);
Gilles Peskine449bd832023-01-11 14:50:10 +0100269 }
Neil Armstrong2d5e3432022-03-21 11:39:52 +0100270#endif /* MBEDTLS_USE_PSA_CRYPTO */
Gilles Peskine449bd832023-01-11 14:50:10 +0100271 return ret;
Manuel Pégourié-Gonnard232edd42014-07-23 16:56:27 +0200272}
273
274/*
275 * Check a cookie
276 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100277int mbedtls_ssl_cookie_check(void *p_ctx,
278 const unsigned char *cookie, size_t cookie_len,
279 const unsigned char *cli_id, size_t cli_id_len)
Manuel Pégourié-Gonnard232edd42014-07-23 16:56:27 +0200280{
Neil Armstrong6d5baf52022-03-07 14:25:18 +0100281#if defined(MBEDTLS_USE_PSA_CRYPTO)
282 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Neil Armstrong79daea22022-03-21 12:05:51 +0100283 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Neil Armstrong6d5baf52022-03-07 14:25:18 +0100284#else
Manuel Pégourié-Gonnarde9030812014-07-23 21:29:11 +0200285 unsigned char ref_hmac[COOKIE_HMAC_LEN];
286 unsigned char *p = ref_hmac;
Neil Armstrong6d5baf52022-03-07 14:25:18 +0100287#endif
288 int ret = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200289 mbedtls_ssl_cookie_ctx *ctx = (mbedtls_ssl_cookie_ctx *) p_ctx;
Manuel Pégourié-Gonnarde9030812014-07-23 21:29:11 +0200290 unsigned long cur_time, cookie_time;
Manuel Pégourié-Gonnard232edd42014-07-23 16:56:27 +0200291
Gilles Peskine449bd832023-01-11 14:50:10 +0100292 if (ctx == NULL || cli_id == NULL) {
293 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
294 }
Manuel Pégourié-Gonnarde9030812014-07-23 21:29:11 +0200295
Gilles Peskine449bd832023-01-11 14:50:10 +0100296 if (cookie_len != COOKIE_LEN) {
297 return -1;
298 }
Manuel Pégourié-Gonnard232edd42014-07-23 16:56:27 +0200299
Neil Armstrong7cd02702022-03-04 15:08:43 +0100300#if defined(MBEDTLS_USE_PSA_CRYPTO)
Gilles Peskine449bd832023-01-11 14:50:10 +0100301 status = psa_mac_verify_setup(&operation, ctx->psa_hmac_key,
302 ctx->psa_hmac_alg);
303 if (status != PSA_SUCCESS) {
Andrzej Kurek8a045ce2022-12-23 11:00:06 -0500304 ret = PSA_TO_MBEDTLS_ERR(status);
Neil Armstrong6d5baf52022-03-07 14:25:18 +0100305 goto exit;
306 }
Neil Armstrong7cd02702022-03-04 15:08:43 +0100307
Gilles Peskine449bd832023-01-11 14:50:10 +0100308 status = psa_mac_update(&operation, cookie, 4);
309 if (status != PSA_SUCCESS) {
Andrzej Kurek8a045ce2022-12-23 11:00:06 -0500310 ret = PSA_TO_MBEDTLS_ERR(status);
Neil Armstrong6d5baf52022-03-07 14:25:18 +0100311 goto exit;
312 }
313
Gilles Peskine449bd832023-01-11 14:50:10 +0100314 status = psa_mac_update(&operation, cli_id,
315 cli_id_len);
316 if (status != PSA_SUCCESS) {
Andrzej Kurek8a045ce2022-12-23 11:00:06 -0500317 ret = PSA_TO_MBEDTLS_ERR(status);
Neil Armstrong6d5baf52022-03-07 14:25:18 +0100318 goto exit;
319 }
320
Gilles Peskine449bd832023-01-11 14:50:10 +0100321 status = psa_mac_verify_finish(&operation, cookie + 4,
322 COOKIE_HMAC_LEN);
323 if (status != PSA_SUCCESS) {
Andrzej Kurek8a045ce2022-12-23 11:00:06 -0500324 ret = PSA_TO_MBEDTLS_ERR(status);
Neil Armstrong6d5baf52022-03-07 14:25:18 +0100325 goto exit;
326 }
Neil Armstrong79daea22022-03-21 12:05:51 +0100327
328 ret = 0;
Neil Armstrong7cd02702022-03-04 15:08:43 +0100329#else
Manuel Pégourié-Gonnard2a84dfd2015-05-28 15:48:09 +0200330#if defined(MBEDTLS_THREADING_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100331 if ((ret = mbedtls_mutex_lock(&ctx->mutex)) != 0) {
332 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_SSL_INTERNAL_ERROR, ret);
Gilles Peskinec2f7b752021-12-13 12:35:08 +0100333 }
Manuel Pégourié-Gonnard2a84dfd2015-05-28 15:48:09 +0200334#endif
335
Gilles Peskine449bd832023-01-11 14:50:10 +0100336 if (ssl_cookie_hmac(&ctx->hmac_ctx, cookie,
337 &p, p + sizeof(ref_hmac),
338 cli_id, cli_id_len) != 0) {
339 ret = -1;
340 }
Manuel Pégourié-Gonnard232edd42014-07-23 16:56:27 +0200341
Gilles Peskine449bd832023-01-11 14:50:10 +0100342#if defined(MBEDTLS_THREADING_C)
343 if (mbedtls_mutex_unlock(&ctx->mutex) != 0) {
344 ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_SSL_INTERNAL_ERROR,
345 MBEDTLS_ERR_THREADING_MUTEX_ERROR);
346 }
347#endif
348
349 if (ret != 0) {
350 goto exit;
351 }
352
353 if (mbedtls_ct_memcmp(cookie + 4, ref_hmac, sizeof(ref_hmac)) != 0) {
Gilles Peskinec2f7b752021-12-13 12:35:08 +0100354 ret = -1;
355 goto exit;
356 }
Neil Armstrong6d5baf52022-03-07 14:25:18 +0100357#endif /* MBEDTLS_USE_PSA_CRYPTO */
Manuel Pégourié-Gonnarde9030812014-07-23 21:29:11 +0200358
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200359#if defined(MBEDTLS_HAVE_TIME)
Gilles Peskine449bd832023-01-11 14:50:10 +0100360 cur_time = (unsigned long) mbedtls_time(NULL);
Manuel Pégourié-Gonnarde9030812014-07-23 21:29:11 +0200361#else
362 cur_time = ctx->serial;
363#endif
364
Thomas Daubneyf9f0ba82023-05-23 17:34:33 +0100365 cookie_time = (unsigned long) MBEDTLS_GET_UINT32_BE(cookie, 0);
Manuel Pégourié-Gonnarde9030812014-07-23 21:29:11 +0200366
Gilles Peskine449bd832023-01-11 14:50:10 +0100367 if (ctx->timeout != 0 && cur_time - cookie_time > ctx->timeout) {
Gilles Peskinec2f7b752021-12-13 12:35:08 +0100368 ret = -1;
369 goto exit;
370 }
Manuel Pégourié-Gonnard232edd42014-07-23 16:56:27 +0200371
Gilles Peskinec2f7b752021-12-13 12:35:08 +0100372exit:
Neil Armstrong6d5baf52022-03-07 14:25:18 +0100373#if defined(MBEDTLS_USE_PSA_CRYPTO)
Gilles Peskine449bd832023-01-11 14:50:10 +0100374 status = psa_mac_abort(&operation);
375 if (status != PSA_SUCCESS) {
Andrzej Kurek8a045ce2022-12-23 11:00:06 -0500376 ret = PSA_TO_MBEDTLS_ERR(status);
Gilles Peskine449bd832023-01-11 14:50:10 +0100377 }
Neil Armstrong6d5baf52022-03-07 14:25:18 +0100378#else
Gilles Peskine449bd832023-01-11 14:50:10 +0100379 mbedtls_platform_zeroize(ref_hmac, sizeof(ref_hmac));
Neil Armstrong6d5baf52022-03-07 14:25:18 +0100380#endif /* MBEDTLS_USE_PSA_CRYPTO */
Gilles Peskine449bd832023-01-11 14:50:10 +0100381 return ret;
Manuel Pégourié-Gonnard232edd42014-07-23 16:56:27 +0200382}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200383#endif /* MBEDTLS_SSL_COOKIE_C */