blob: 73f9c7f4710b0c2e4496f0088232dabc23de4c4a [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * SSLv3/TLSv1 shared functions
3 *
Bence Szépkúti1e148272020-08-07 13:07:28 +02004 * Copyright The Mbed TLS Contributors
Dave Rodgman7ff79652023-11-03 12:04:52 +00005 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
Paul Bakker5121ce52009-01-03 21:22:43 +00006 */
7/*
8 * The SSL 3.0 specification was drafted by Netscape in 1996,
9 * and became an IETF standard in 1999.
10 *
11 * http://wp.netscape.com/eng/ssl3/
12 * http://www.ietf.org/rfc/rfc2246.txt
13 * http://www.ietf.org/rfc/rfc4346.txt
14 */
15
Gilles Peskinedb09ef62020-06-03 01:43:33 +020016#include "common.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000017
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020018#if defined(MBEDTLS_SSL_TLS_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000019
SimonBd5800b72016-04-26 07:43:27 +010020#include "mbedtls/platform.h"
SimonBd5800b72016-04-26 07:43:27 +010021
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000022#include "mbedtls/ssl.h"
Manuel Pégourié-Gonnard5e94dde2015-05-26 11:57:05 +020023#include "mbedtls/ssl_internal.h"
Janos Follath73c616b2019-12-18 15:07:04 +000024#include "mbedtls/debug.h"
25#include "mbedtls/error.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050026#include "mbedtls/platform_util.h"
Hanno Beckera835da52019-05-16 12:39:07 +010027#include "mbedtls/version.h"
Gabor Mezeie24dea82021-10-19 12:22:25 +020028#include "mbedtls/constant_time.h"
Paul Bakker0be444a2013-08-27 21:55:01 +020029
Rich Evans00ab4702015-02-06 13:43:58 +000030#include <string.h>
31
Andrzej Kurekd6db9be2019-01-10 05:27:10 -050032#if defined(MBEDTLS_USE_PSA_CRYPTO)
33#include "mbedtls/psa_util.h"
34#include "psa/crypto.h"
35#endif
36
Janos Follath23bdca02016-10-07 14:47:14 +010037#if defined(MBEDTLS_X509_CRT_PARSE_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000038#include "mbedtls/oid.h"
Manuel Pégourié-Gonnard0408fd12014-04-11 11:06:22 +020039#endif
40
Gilles Peskineff257152025-02-20 13:57:51 +010041#if defined(MBEDTLS_X509_CRT_PARSE_C)
Gilles Peskine3a2f75d2025-02-12 23:28:48 +010042
Gilles Peskinef33c45f2025-02-12 23:53:25 +010043/* A magic value for `ssl->hostname` indicating that
44 * mbedtls_ssl_set_hostname() has been called with `NULL`.
45 * If mbedtls_ssl_set_hostname() has never been called on `ssl`, then
46 * `ssl->hostname == NULL`. */
47static const char *const ssl_hostname_skip_cn_verification = "";
48
Gilles Peskine3a2f75d2025-02-12 23:28:48 +010049#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
50/** Whether mbedtls_ssl_set_hostname() has been called.
51 *
52 * \param[in] ssl SSL context
53 *
54 * \return \c 1 if mbedtls_ssl_set_hostname() has been called on \p ssl
55 * (including `mbedtls_ssl_set_hostname(ssl, NULL)`),
56 * otherwise \c 0.
57 */
58static int mbedtls_ssl_has_set_hostname_been_called(
59 const mbedtls_ssl_context *ssl)
60{
Gilles Peskine3a2f75d2025-02-12 23:28:48 +010061 return ssl->hostname != NULL;
62}
63#endif
64
Gilles Peskine3a2f75d2025-02-12 23:28:48 +010065const char *mbedtls_ssl_get_hostname_pointer(const mbedtls_ssl_context *ssl)
66{
Gilles Peskinef33c45f2025-02-12 23:53:25 +010067 if (ssl->hostname == ssl_hostname_skip_cn_verification) {
68 return NULL;
69 }
Gilles Peskine3a2f75d2025-02-12 23:28:48 +010070 return ssl->hostname;
71}
72
73static void mbedtls_ssl_free_hostname(mbedtls_ssl_context *ssl)
74{
Gilles Peskinef33c45f2025-02-12 23:53:25 +010075 if (ssl->hostname != NULL &&
76 ssl->hostname != ssl_hostname_skip_cn_verification) {
Gilles Peskine3a2f75d2025-02-12 23:28:48 +010077 mbedtls_platform_zeroize(ssl->hostname, strlen(ssl->hostname));
78 mbedtls_free(ssl->hostname);
79 }
80 ssl->hostname = NULL;
81}
82
Gilles Peskineff257152025-02-20 13:57:51 +010083int mbedtls_ssl_set_hostname(mbedtls_ssl_context *ssl, const char *hostname)
84{
85 /* Initialize to suppress unnecessary compiler warning */
86 size_t hostname_len = 0;
87
88 /* Check if new hostname is valid before
89 * making any change to current one */
90 if (hostname != NULL) {
91 hostname_len = strlen(hostname);
92
93 if (hostname_len > MBEDTLS_SSL_MAX_HOST_NAME_LEN) {
94 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
95 }
96 }
97
98 /* Now it's clear that we will overwrite the old hostname,
99 * so we can free it safely */
Gilles Peskine3a2f75d2025-02-12 23:28:48 +0100100 mbedtls_ssl_free_hostname(ssl);
Gilles Peskineff257152025-02-20 13:57:51 +0100101
Gilles Peskineff257152025-02-20 13:57:51 +0100102 if (hostname == NULL) {
Gilles Peskinef33c45f2025-02-12 23:53:25 +0100103 /* Passing NULL as hostname clears the old one, but leaves a
104 * special marker to indicate that mbedtls_ssl_set_hostname()
105 * has been called. */
106 /* ssl->hostname should be const, but isn't. We won't actually
107 * write to the buffer, so it's ok to cast away the const. */
108 ssl->hostname = (char *) ssl_hostname_skip_cn_verification;
Gilles Peskineff257152025-02-20 13:57:51 +0100109 } else {
110 ssl->hostname = mbedtls_calloc(1, hostname_len + 1);
111 if (ssl->hostname == NULL) {
Gilles Peskinef33c45f2025-02-12 23:53:25 +0100112 /* mbedtls_ssl_set_hostname() has been called, but unsuccessfully.
113 * Leave ssl->hostname in the same state as if the function had
114 * not been called, i.e. a null pointer. */
Gilles Peskineff257152025-02-20 13:57:51 +0100115 return MBEDTLS_ERR_SSL_ALLOC_FAILED;
116 }
117
118 memcpy(ssl->hostname, hostname, hostname_len);
119
120 ssl->hostname[hostname_len] = '\0';
121 }
122
123 return 0;
124}
125#endif /* MBEDTLS_X509_CRT_PARSE_C */
126
Manuel Pégourié-Gonnard286a1362015-05-13 16:22:05 +0200127#if defined(MBEDTLS_SSL_PROTO_DTLS)
Hanno Becker2b1e3542018-08-06 11:19:13 +0100128
Hanno Beckera0e20d02019-05-15 14:03:01 +0100129#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
Hanno Beckerf8542cf2019-04-09 15:22:03 +0100130/* Top-level Connection ID API */
131
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100132int mbedtls_ssl_conf_cid(mbedtls_ssl_config *conf,
133 size_t len,
134 int ignore_other_cid)
Hanno Beckerad4a1372019-05-03 13:06:44 +0100135{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100136 if (len > MBEDTLS_SSL_CID_IN_LEN_MAX) {
137 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
138 }
Hanno Beckerad4a1372019-05-03 13:06:44 +0100139
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100140 if (ignore_other_cid != MBEDTLS_SSL_UNEXPECTED_CID_FAIL &&
141 ignore_other_cid != MBEDTLS_SSL_UNEXPECTED_CID_IGNORE) {
142 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
Hanno Becker611ac772019-05-14 11:45:26 +0100143 }
144
145 conf->ignore_unexpected_cid = ignore_other_cid;
Hanno Beckerad4a1372019-05-03 13:06:44 +0100146 conf->cid_len = len;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100147 return 0;
Hanno Beckerad4a1372019-05-03 13:06:44 +0100148}
149
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100150int mbedtls_ssl_set_cid(mbedtls_ssl_context *ssl,
151 int enable,
152 unsigned char const *own_cid,
153 size_t own_cid_len)
Hanno Beckerf8542cf2019-04-09 15:22:03 +0100154{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100155 if (ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
156 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
157 }
Hanno Becker76a79ab2019-05-03 14:38:32 +0100158
Hanno Beckerca092242019-04-25 16:01:49 +0100159 ssl->negotiate_cid = enable;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100160 if (enable == MBEDTLS_SSL_CID_DISABLED) {
161 MBEDTLS_SSL_DEBUG_MSG(3, ("Disable use of CID extension."));
162 return 0;
Hanno Beckerca092242019-04-25 16:01:49 +0100163 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100164 MBEDTLS_SSL_DEBUG_MSG(3, ("Enable use of CID extension."));
165 MBEDTLS_SSL_DEBUG_BUF(3, "Own CID", own_cid, own_cid_len);
Hanno Beckerca092242019-04-25 16:01:49 +0100166
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100167 if (own_cid_len != ssl->conf->cid_len) {
168 MBEDTLS_SSL_DEBUG_MSG(3, ("CID length %u does not match CID length %u in config",
169 (unsigned) own_cid_len,
170 (unsigned) ssl->conf->cid_len));
171 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
Hanno Beckerca092242019-04-25 16:01:49 +0100172 }
173
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100174 memcpy(ssl->own_cid, own_cid, own_cid_len);
Hanno Beckerb7ee0cf2019-04-30 14:07:31 +0100175 /* Truncation is not an issue here because
176 * MBEDTLS_SSL_CID_IN_LEN_MAX at most 255. */
177 ssl->own_cid_len = (uint8_t) own_cid_len;
Hanno Beckerca092242019-04-25 16:01:49 +0100178
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100179 return 0;
Hanno Beckerf8542cf2019-04-09 15:22:03 +0100180}
181
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100182int mbedtls_ssl_get_peer_cid(mbedtls_ssl_context *ssl,
183 int *enabled,
184 unsigned char peer_cid[MBEDTLS_SSL_CID_OUT_LEN_MAX],
185 size_t *peer_cid_len)
Hanno Beckerf8542cf2019-04-09 15:22:03 +0100186{
Hanno Beckerf8542cf2019-04-09 15:22:03 +0100187 *enabled = MBEDTLS_SSL_CID_DISABLED;
Hanno Beckerb1f89cd2019-04-26 17:08:02 +0100188
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100189 if (ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM ||
190 ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER) {
191 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
Hanno Becker76a79ab2019-05-03 14:38:32 +0100192 }
Hanno Beckerb1f89cd2019-04-26 17:08:02 +0100193
Hanno Beckerc5f24222019-05-03 12:54:52 +0100194 /* We report MBEDTLS_SSL_CID_DISABLED in case the CID extensions
195 * were used, but client and server requested the empty CID.
196 * This is indistinguishable from not using the CID extension
197 * in the first place. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100198 if (ssl->transform_in->in_cid_len == 0 &&
199 ssl->transform_in->out_cid_len == 0) {
200 return 0;
Hanno Beckerb1f89cd2019-04-26 17:08:02 +0100201 }
202
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100203 if (peer_cid_len != NULL) {
Hanno Becker615ef172019-05-22 16:50:35 +0100204 *peer_cid_len = ssl->transform_in->out_cid_len;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100205 if (peer_cid != NULL) {
206 memcpy(peer_cid, ssl->transform_in->out_cid,
207 ssl->transform_in->out_cid_len);
Hanno Becker615ef172019-05-22 16:50:35 +0100208 }
209 }
Hanno Beckerb1f89cd2019-04-26 17:08:02 +0100210
211 *enabled = MBEDTLS_SSL_CID_ENABLED;
212
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100213 return 0;
Hanno Beckerf8542cf2019-04-09 15:22:03 +0100214}
Hanno Beckera0e20d02019-05-15 14:03:01 +0100215#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
Hanno Beckerf8542cf2019-04-09 15:22:03 +0100216
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200217#endif /* MBEDTLS_SSL_PROTO_DTLS */
Manuel Pégourié-Gonnard0ac247f2014-09-30 22:21:31 +0200218
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200219#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
Manuel Pégourié-Gonnard581e6b62013-07-18 12:32:27 +0200220/*
221 * Convert max_fragment_length codes to length.
222 * RFC 6066 says:
223 * enum{
224 * 2^9(1), 2^10(2), 2^11(3), 2^12(4), (255)
225 * } MaxFragmentLength;
226 * and we add 0 -> extension unused
227 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100228static unsigned int ssl_mfl_code_to_length(int mfl)
Manuel Pégourié-Gonnard581e6b62013-07-18 12:32:27 +0200229{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100230 switch (mfl) {
231 case MBEDTLS_SSL_MAX_FRAG_LEN_NONE:
232 return MBEDTLS_TLS_EXT_ADV_CONTENT_LEN;
233 case MBEDTLS_SSL_MAX_FRAG_LEN_512:
234 return 512;
235 case MBEDTLS_SSL_MAX_FRAG_LEN_1024:
236 return 1024;
237 case MBEDTLS_SSL_MAX_FRAG_LEN_2048:
238 return 2048;
239 case MBEDTLS_SSL_MAX_FRAG_LEN_4096:
240 return 4096;
241 default:
242 return MBEDTLS_TLS_EXT_ADV_CONTENT_LEN;
Angus Grattond8213d02016-05-25 20:56:48 +1000243 }
244}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200245#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
Manuel Pégourié-Gonnard581e6b62013-07-18 12:32:27 +0200246
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100247int mbedtls_ssl_session_copy(mbedtls_ssl_session *dst,
248 const mbedtls_ssl_session *src)
Manuel Pégourié-Gonnard06650f62013-08-02 15:34:52 +0200249{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100250 mbedtls_ssl_session_free(dst);
251 memcpy(dst, src, sizeof(mbedtls_ssl_session));
Manuel Pégourié-Gonnard06650f62013-08-02 15:34:52 +0200252
吴敬辉0f6c6bc2021-11-29 10:46:35 +0800253#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
254 dst->ticket = NULL;
255#endif
256
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200257#if defined(MBEDTLS_X509_CRT_PARSE_C)
Hanno Becker6d1986e2019-02-07 12:27:42 +0000258
259#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100260 if (src->peer_cert != NULL) {
Janos Follath865b3eb2019-12-16 11:46:15 +0000261 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker2292d1f2013-09-15 17:06:49 +0200262
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100263 dst->peer_cert = mbedtls_calloc(1, sizeof(mbedtls_x509_crt));
264 if (dst->peer_cert == NULL) {
265 return MBEDTLS_ERR_SSL_ALLOC_FAILED;
266 }
Manuel Pégourié-Gonnard06650f62013-08-02 15:34:52 +0200267
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100268 mbedtls_x509_crt_init(dst->peer_cert);
Manuel Pégourié-Gonnard06650f62013-08-02 15:34:52 +0200269
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100270 if ((ret = mbedtls_x509_crt_parse_der(dst->peer_cert, src->peer_cert->raw.p,
271 src->peer_cert->raw.len)) != 0) {
272 mbedtls_free(dst->peer_cert);
Manuel Pégourié-Gonnard06650f62013-08-02 15:34:52 +0200273 dst->peer_cert = NULL;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100274 return ret;
Manuel Pégourié-Gonnard06650f62013-08-02 15:34:52 +0200275 }
276 }
Hanno Becker6d1986e2019-02-07 12:27:42 +0000277#else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100278 if (src->peer_cert_digest != NULL) {
Hanno Becker9198ad12019-02-05 17:00:50 +0000279 dst->peer_cert_digest =
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100280 mbedtls_calloc(1, src->peer_cert_digest_len);
281 if (dst->peer_cert_digest == NULL) {
282 return MBEDTLS_ERR_SSL_ALLOC_FAILED;
283 }
Hanno Becker9198ad12019-02-05 17:00:50 +0000284
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100285 memcpy(dst->peer_cert_digest, src->peer_cert_digest,
286 src->peer_cert_digest_len);
Hanno Becker9198ad12019-02-05 17:00:50 +0000287 dst->peer_cert_digest_type = src->peer_cert_digest_type;
Hanno Beckeraccc5992019-02-25 10:06:59 +0000288 dst->peer_cert_digest_len = src->peer_cert_digest_len;
Hanno Becker9198ad12019-02-05 17:00:50 +0000289 }
290#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
291
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200292#endif /* MBEDTLS_X509_CRT_PARSE_C */
Manuel Pégourié-Gonnard06650f62013-08-02 15:34:52 +0200293
Manuel Pégourié-Gonnardb596abf2015-05-20 10:45:29 +0200294#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100295 if (src->ticket != NULL) {
296 dst->ticket = mbedtls_calloc(1, src->ticket_len);
297 if (dst->ticket == NULL) {
298 return MBEDTLS_ERR_SSL_ALLOC_FAILED;
299 }
Manuel Pégourié-Gonnard06650f62013-08-02 15:34:52 +0200300
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100301 memcpy(dst->ticket, src->ticket, src->ticket_len);
Manuel Pégourié-Gonnard06650f62013-08-02 15:34:52 +0200302 }
Manuel Pégourié-Gonnardb596abf2015-05-20 10:45:29 +0200303#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */
Manuel Pégourié-Gonnard06650f62013-08-02 15:34:52 +0200304
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100305 return 0;
Manuel Pégourié-Gonnard06650f62013-08-02 15:34:52 +0200306}
307
Andrzej Kurek0afa2a12020-03-03 10:39:58 -0500308#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +0200309MBEDTLS_CHECK_RETURN_CRITICAL
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100310static int resize_buffer(unsigned char **buffer, size_t len_new, size_t *len_old)
Andrzej Kurek0afa2a12020-03-03 10:39:58 -0500311{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100312 unsigned char *resized_buffer = mbedtls_calloc(1, len_new);
313 if (resized_buffer == NULL) {
Andrzej Kurek0afa2a12020-03-03 10:39:58 -0500314 return -1;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100315 }
Andrzej Kurek0afa2a12020-03-03 10:39:58 -0500316
317 /* We want to copy len_new bytes when downsizing the buffer, and
318 * len_old bytes when upsizing, so we choose the smaller of two sizes,
319 * to fit one buffer into another. Size checks, ensuring that no data is
320 * lost, are done outside of this function. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100321 memcpy(resized_buffer, *buffer,
322 (len_new < *len_old) ? len_new : *len_old);
323 mbedtls_platform_zeroize(*buffer, *len_old);
324 mbedtls_free(*buffer);
Andrzej Kurek0afa2a12020-03-03 10:39:58 -0500325
326 *buffer = resized_buffer;
327 *len_old = len_new;
328
329 return 0;
330}
Andrzej Kurek4a063792020-10-21 15:08:44 +0200331
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100332static void handle_buffer_resizing(mbedtls_ssl_context *ssl, int downsizing,
333 size_t in_buf_new_len,
334 size_t out_buf_new_len)
Andrzej Kurek4a063792020-10-21 15:08:44 +0200335{
336 int modified = 0;
337 size_t written_in = 0, iv_offset_in = 0, len_offset_in = 0;
338 size_t written_out = 0, iv_offset_out = 0, len_offset_out = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100339 if (ssl->in_buf != NULL) {
Andrzej Kurek4a063792020-10-21 15:08:44 +0200340 written_in = ssl->in_msg - ssl->in_buf;
341 iv_offset_in = ssl->in_iv - ssl->in_buf;
342 len_offset_in = ssl->in_len - ssl->in_buf;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100343 if (downsizing ?
Andrzej Kurek4a063792020-10-21 15:08:44 +0200344 ssl->in_buf_len > in_buf_new_len && ssl->in_left < in_buf_new_len :
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100345 ssl->in_buf_len < in_buf_new_len) {
346 if (resize_buffer(&ssl->in_buf, in_buf_new_len, &ssl->in_buf_len) != 0) {
347 MBEDTLS_SSL_DEBUG_MSG(1, ("input buffer resizing failed - out of memory"));
348 } else {
349 MBEDTLS_SSL_DEBUG_MSG(2, ("Reallocating in_buf to %" MBEDTLS_PRINTF_SIZET,
350 in_buf_new_len));
Andrzej Kurek4a063792020-10-21 15:08:44 +0200351 modified = 1;
352 }
353 }
354 }
355
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100356 if (ssl->out_buf != NULL) {
Andrzej Kurek4a063792020-10-21 15:08:44 +0200357 written_out = ssl->out_msg - ssl->out_buf;
358 iv_offset_out = ssl->out_iv - ssl->out_buf;
359 len_offset_out = ssl->out_len - ssl->out_buf;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100360 if (downsizing ?
Andrzej Kurek4a063792020-10-21 15:08:44 +0200361 ssl->out_buf_len > out_buf_new_len && ssl->out_left < out_buf_new_len :
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100362 ssl->out_buf_len < out_buf_new_len) {
363 if (resize_buffer(&ssl->out_buf, out_buf_new_len, &ssl->out_buf_len) != 0) {
364 MBEDTLS_SSL_DEBUG_MSG(1, ("output buffer resizing failed - out of memory"));
365 } else {
366 MBEDTLS_SSL_DEBUG_MSG(2, ("Reallocating out_buf to %" MBEDTLS_PRINTF_SIZET,
367 out_buf_new_len));
Andrzej Kurek4a063792020-10-21 15:08:44 +0200368 modified = 1;
369 }
370 }
371 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100372 if (modified) {
Andrzej Kurek4a063792020-10-21 15:08:44 +0200373 /* Update pointers here to avoid doing it twice. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100374 mbedtls_ssl_reset_in_out_pointers(ssl);
Andrzej Kurek4a063792020-10-21 15:08:44 +0200375 /* Fields below might not be properly updated with record
376 * splitting or with CID, so they are manually updated here. */
377 ssl->out_msg = ssl->out_buf + written_out;
378 ssl->out_len = ssl->out_buf + len_offset_out;
379 ssl->out_iv = ssl->out_buf + iv_offset_out;
380
381 ssl->in_msg = ssl->in_buf + written_in;
382 ssl->in_len = ssl->in_buf + len_offset_in;
383 ssl->in_iv = ssl->in_buf + iv_offset_in;
384 }
385}
Andrzej Kurek0afa2a12020-03-03 10:39:58 -0500386#endif /* MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH */
387
Paul Bakker5121ce52009-01-03 21:22:43 +0000388/*
389 * Key material generation
390 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200391#if defined(MBEDTLS_SSL_PROTO_SSL3)
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +0200392MBEDTLS_CHECK_RETURN_CRITICAL
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100393static int ssl3_prf(const unsigned char *secret, size_t slen,
394 const char *label,
395 const unsigned char *random, size_t rlen,
396 unsigned char *dstbuf, size_t dlen)
Paul Bakker5f70b252012-09-13 14:23:06 +0000397{
Andres Amaya Garcia33952502017-07-20 16:29:16 +0100398 int ret = 0;
Paul Bakker5f70b252012-09-13 14:23:06 +0000399 size_t i;
Manuel Pégourié-Gonnardc0bf01e2015-07-06 16:11:18 +0200400 mbedtls_md5_context md5;
401 mbedtls_sha1_context sha1;
Paul Bakker5f70b252012-09-13 14:23:06 +0000402 unsigned char padding[16];
403 unsigned char sha1sum[20];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100404 ((void) label);
Paul Bakker5f70b252012-09-13 14:23:06 +0000405
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100406 mbedtls_md5_init(&md5);
407 mbedtls_sha1_init(&sha1);
Paul Bakker5b4af392014-06-26 12:09:34 +0200408
Paul Bakker5f70b252012-09-13 14:23:06 +0000409 /*
410 * SSLv3:
411 * block =
412 * MD5( secret + SHA1( 'A' + secret + random ) ) +
413 * MD5( secret + SHA1( 'BB' + secret + random ) ) +
414 * MD5( secret + SHA1( 'CCC' + secret + random ) ) +
415 * ...
416 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100417 for (i = 0; i < dlen / 16; i++) {
418 memset(padding, (unsigned char) ('A' + i), 1 + i);
Paul Bakker5f70b252012-09-13 14:23:06 +0000419
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100420 if ((ret = mbedtls_sha1_starts_ret(&sha1)) != 0) {
Andres Amaya Garcia1a607a12017-06-29 17:09:42 +0100421 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100422 }
423 if ((ret = mbedtls_sha1_update_ret(&sha1, padding, 1 + i)) != 0) {
Andres Amaya Garcia1a607a12017-06-29 17:09:42 +0100424 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100425 }
426 if ((ret = mbedtls_sha1_update_ret(&sha1, secret, slen)) != 0) {
Andres Amaya Garcia1a607a12017-06-29 17:09:42 +0100427 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100428 }
429 if ((ret = mbedtls_sha1_update_ret(&sha1, random, rlen)) != 0) {
Andres Amaya Garcia1a607a12017-06-29 17:09:42 +0100430 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100431 }
432 if ((ret = mbedtls_sha1_finish_ret(&sha1, sha1sum)) != 0) {
Andres Amaya Garcia1a607a12017-06-29 17:09:42 +0100433 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100434 }
Paul Bakker5f70b252012-09-13 14:23:06 +0000435
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100436 if ((ret = mbedtls_md5_starts_ret(&md5)) != 0) {
Andres Amaya Garcia1a607a12017-06-29 17:09:42 +0100437 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100438 }
439 if ((ret = mbedtls_md5_update_ret(&md5, secret, slen)) != 0) {
Andres Amaya Garcia1a607a12017-06-29 17:09:42 +0100440 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100441 }
442 if ((ret = mbedtls_md5_update_ret(&md5, sha1sum, 20)) != 0) {
Andres Amaya Garcia1a607a12017-06-29 17:09:42 +0100443 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100444 }
445 if ((ret = mbedtls_md5_finish_ret(&md5, dstbuf + i * 16)) != 0) {
Andres Amaya Garcia1a607a12017-06-29 17:09:42 +0100446 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100447 }
Paul Bakker5f70b252012-09-13 14:23:06 +0000448 }
449
Andres Amaya Garcia1a607a12017-06-29 17:09:42 +0100450exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100451 mbedtls_md5_free(&md5);
452 mbedtls_sha1_free(&sha1);
Paul Bakker5f70b252012-09-13 14:23:06 +0000453
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100454 mbedtls_platform_zeroize(padding, sizeof(padding));
455 mbedtls_platform_zeroize(sha1sum, sizeof(sha1sum));
Paul Bakker5f70b252012-09-13 14:23:06 +0000456
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100457 return ret;
Paul Bakker5f70b252012-09-13 14:23:06 +0000458}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200459#endif /* MBEDTLS_SSL_PROTO_SSL3 */
Paul Bakker5f70b252012-09-13 14:23:06 +0000460
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200461#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1)
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +0200462MBEDTLS_CHECK_RETURN_CRITICAL
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100463static int tls1_prf(const unsigned char *secret, size_t slen,
464 const char *label,
465 const unsigned char *random, size_t rlen,
466 unsigned char *dstbuf, size_t dlen)
Paul Bakker5121ce52009-01-03 21:22:43 +0000467{
Paul Bakker23986e52011-04-24 08:57:21 +0000468 size_t nb, hs;
469 size_t i, j, k;
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +0200470 const unsigned char *S1, *S2;
Ron Eldor3b350852019-05-07 18:31:49 +0300471 unsigned char *tmp;
472 size_t tmp_len = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000473 unsigned char h_i[20];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200474 const mbedtls_md_info_t *md_info;
475 mbedtls_md_context_t md_ctx;
Janos Follath865b3eb2019-12-16 11:46:15 +0000476 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnardb7fcca32015-03-26 11:41:28 +0100477
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100478 mbedtls_md_init(&md_ctx);
Paul Bakker5121ce52009-01-03 21:22:43 +0000479
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100480 tmp_len = 20 + strlen(label) + rlen;
481 tmp = mbedtls_calloc(1, tmp_len);
482 if (tmp == NULL) {
Ron Eldor3b350852019-05-07 18:31:49 +0300483 ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
484 goto exit;
485 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000486
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100487 hs = (slen + 1) / 2;
Paul Bakker5121ce52009-01-03 21:22:43 +0000488 S1 = secret;
489 S2 = secret + slen - hs;
490
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100491 nb = strlen(label);
492 memcpy(tmp + 20, label, nb);
493 memcpy(tmp + 20 + nb, random, rlen);
Paul Bakker5121ce52009-01-03 21:22:43 +0000494 nb += rlen;
495
496 /*
497 * First compute P_md5(secret,label+random)[0..dlen]
498 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100499 if ((md_info = mbedtls_md_info_from_type(MBEDTLS_MD_MD5)) == NULL) {
Ron Eldor3b350852019-05-07 18:31:49 +0300500 ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR;
501 goto exit;
502 }
Manuel Pégourié-Gonnard7da726b2015-03-24 18:08:19 +0100503
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100504 if ((ret = mbedtls_md_setup(&md_ctx, md_info, 1)) != 0) {
Ron Eldor3b350852019-05-07 18:31:49 +0300505 goto exit;
506 }
Manuel Pégourié-Gonnardb7fcca32015-03-26 11:41:28 +0100507
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100508 ret = mbedtls_md_hmac_starts(&md_ctx, S1, hs);
509 if (ret != 0) {
Gilles Peskine2b3f21d2021-12-10 21:35:10 +0100510 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100511 }
512 ret = mbedtls_md_hmac_update(&md_ctx, tmp + 20, nb);
513 if (ret != 0) {
Gilles Peskine2b3f21d2021-12-10 21:35:10 +0100514 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100515 }
516 ret = mbedtls_md_hmac_finish(&md_ctx, 4 + tmp);
517 if (ret != 0) {
Gilles Peskine2b3f21d2021-12-10 21:35:10 +0100518 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100519 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000520
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100521 for (i = 0; i < dlen; i += 16) {
522 ret = mbedtls_md_hmac_reset(&md_ctx);
523 if (ret != 0) {
Gilles Peskine2b3f21d2021-12-10 21:35:10 +0100524 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100525 }
526 ret = mbedtls_md_hmac_update(&md_ctx, 4 + tmp, 16 + nb);
527 if (ret != 0) {
Gilles Peskine2b3f21d2021-12-10 21:35:10 +0100528 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100529 }
530 ret = mbedtls_md_hmac_finish(&md_ctx, h_i);
531 if (ret != 0) {
Gilles Peskine2b3f21d2021-12-10 21:35:10 +0100532 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100533 }
Manuel Pégourié-Gonnardb7fcca32015-03-26 11:41:28 +0100534
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100535 ret = mbedtls_md_hmac_reset(&md_ctx);
536 if (ret != 0) {
Gilles Peskine2b3f21d2021-12-10 21:35:10 +0100537 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100538 }
539 ret = mbedtls_md_hmac_update(&md_ctx, 4 + tmp, 16);
540 if (ret != 0) {
Gilles Peskine2b3f21d2021-12-10 21:35:10 +0100541 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100542 }
543 ret = mbedtls_md_hmac_finish(&md_ctx, 4 + tmp);
544 if (ret != 0) {
Gilles Peskine2b3f21d2021-12-10 21:35:10 +0100545 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100546 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000547
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100548 k = (i + 16 > dlen) ? dlen % 16 : 16;
Paul Bakker5121ce52009-01-03 21:22:43 +0000549
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100550 for (j = 0; j < k; j++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000551 dstbuf[i + j] = h_i[j];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100552 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000553 }
554
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100555 mbedtls_md_free(&md_ctx);
Manuel Pégourié-Gonnardb7fcca32015-03-26 11:41:28 +0100556
Paul Bakker5121ce52009-01-03 21:22:43 +0000557 /*
558 * XOR out with P_sha1(secret,label+random)[0..dlen]
559 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100560 if ((md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA1)) == NULL) {
Ron Eldor3b350852019-05-07 18:31:49 +0300561 ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR;
562 goto exit;
563 }
Manuel Pégourié-Gonnard7da726b2015-03-24 18:08:19 +0100564
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100565 if ((ret = mbedtls_md_setup(&md_ctx, md_info, 1)) != 0) {
Ron Eldor3b350852019-05-07 18:31:49 +0300566 goto exit;
567 }
Manuel Pégourié-Gonnardb7fcca32015-03-26 11:41:28 +0100568
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100569 ret = mbedtls_md_hmac_starts(&md_ctx, S2, hs);
570 if (ret != 0) {
Gilles Peskine2b3f21d2021-12-10 21:35:10 +0100571 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100572 }
573 ret = mbedtls_md_hmac_update(&md_ctx, tmp + 20, nb);
574 if (ret != 0) {
Gilles Peskine2b3f21d2021-12-10 21:35:10 +0100575 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100576 }
577 ret = mbedtls_md_hmac_finish(&md_ctx, tmp);
578 if (ret != 0) {
Gilles Peskine2b3f21d2021-12-10 21:35:10 +0100579 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100580 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000581
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100582 for (i = 0; i < dlen; i += 20) {
583 ret = mbedtls_md_hmac_reset(&md_ctx);
584 if (ret != 0) {
Gilles Peskine2b3f21d2021-12-10 21:35:10 +0100585 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100586 }
587 ret = mbedtls_md_hmac_update(&md_ctx, tmp, 20 + nb);
588 if (ret != 0) {
Gilles Peskine2b3f21d2021-12-10 21:35:10 +0100589 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100590 }
591 ret = mbedtls_md_hmac_finish(&md_ctx, h_i);
592 if (ret != 0) {
Gilles Peskine2b3f21d2021-12-10 21:35:10 +0100593 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100594 }
Manuel Pégourié-Gonnardb7fcca32015-03-26 11:41:28 +0100595
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100596 ret = mbedtls_md_hmac_reset(&md_ctx);
597 if (ret != 0) {
Gilles Peskine2b3f21d2021-12-10 21:35:10 +0100598 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100599 }
600 ret = mbedtls_md_hmac_update(&md_ctx, tmp, 20);
601 if (ret != 0) {
Gilles Peskine2b3f21d2021-12-10 21:35:10 +0100602 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100603 }
604 ret = mbedtls_md_hmac_finish(&md_ctx, tmp);
605 if (ret != 0) {
Gilles Peskine2b3f21d2021-12-10 21:35:10 +0100606 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100607 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000608
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100609 k = (i + 20 > dlen) ? dlen % 20 : 20;
Paul Bakker5121ce52009-01-03 21:22:43 +0000610
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100611 for (j = 0; j < k; j++) {
612 dstbuf[i + j] = (unsigned char) (dstbuf[i + j] ^ h_i[j]);
613 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000614 }
615
Ron Eldor3b350852019-05-07 18:31:49 +0300616exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100617 mbedtls_md_free(&md_ctx);
Manuel Pégourié-Gonnardb7fcca32015-03-26 11:41:28 +0100618
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100619 mbedtls_platform_zeroize(tmp, tmp_len);
620 mbedtls_platform_zeroize(h_i, sizeof(h_i));
Paul Bakker5121ce52009-01-03 21:22:43 +0000621
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100622 mbedtls_free(tmp);
623 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000624}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200625#endif /* MBEDTLS_SSL_PROTO_TLS1) || MBEDTLS_SSL_PROTO_TLS1_1 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000626
Andrzej Kurekc929a822019-01-14 03:51:11 -0500627#if defined(MBEDTLS_USE_PSA_CRYPTO)
David Horstmann09072662025-03-12 12:03:13 +0000628static int mbedtls_ssl_md_error_from_psa(psa_status_t status)
629{
630 switch (status) {
631 case PSA_ERROR_NOT_SUPPORTED:
632 return MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE;
633 case PSA_ERROR_BAD_STATE: /* Intentional fallthrough */
634 case PSA_ERROR_BUFFER_TOO_SMALL:
635 return MBEDTLS_ERR_MD_BAD_INPUT_DATA;
636 case PSA_ERROR_INSUFFICIENT_MEMORY:
637 return MBEDTLS_ERR_MD_ALLOC_FAILED;
638 default:
639 return MBEDTLS_ERR_MD_HW_ACCEL_FAILED;
640 }
641}
David Horstmann226daac2025-03-12 13:58:01 +0000642#endif
643
644#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
645#if defined(MBEDTLS_USE_PSA_CRYPTO)
David Horstmann09072662025-03-12 12:03:13 +0000646
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100647static psa_status_t setup_psa_key_derivation(psa_key_derivation_operation_t *derivation,
648 psa_key_id_t key,
649 psa_algorithm_t alg,
650 const unsigned char *seed, size_t seed_length,
651 const unsigned char *label, size_t label_length,
652 size_t capacity)
k-stachowiak81053a52019-08-17 10:30:28 +0200653{
654 psa_status_t status;
655
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100656 status = psa_key_derivation_setup(derivation, alg);
657 if (status != PSA_SUCCESS) {
658 return status;
659 }
k-stachowiak81053a52019-08-17 10:30:28 +0200660
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100661 if (PSA_ALG_IS_TLS12_PRF(alg) || PSA_ALG_IS_TLS12_PSK_TO_MS(alg)) {
662 status = psa_key_derivation_input_bytes(derivation,
663 PSA_KEY_DERIVATION_INPUT_SEED,
664 seed, seed_length);
665 if (status != PSA_SUCCESS) {
666 return status;
667 }
k-stachowiak81053a52019-08-17 10:30:28 +0200668
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100669 if (mbedtls_svc_key_id_is_null(key)) {
Gilles Peskine311f54d2019-09-23 18:19:22 +0200670 status = psa_key_derivation_input_bytes(
671 derivation, PSA_KEY_DERIVATION_INPUT_SECRET,
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100672 NULL, 0);
673 } else {
Gilles Peskine311f54d2019-09-23 18:19:22 +0200674 status = psa_key_derivation_input_key(
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100675 derivation, PSA_KEY_DERIVATION_INPUT_SECRET, key);
Gilles Peskine311f54d2019-09-23 18:19:22 +0200676 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100677 if (status != PSA_SUCCESS) {
678 return status;
679 }
k-stachowiak81053a52019-08-17 10:30:28 +0200680
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100681 status = psa_key_derivation_input_bytes(derivation,
682 PSA_KEY_DERIVATION_INPUT_LABEL,
683 label, label_length);
684 if (status != PSA_SUCCESS) {
685 return status;
686 }
687 } else {
688 return PSA_ERROR_NOT_SUPPORTED;
k-stachowiak81053a52019-08-17 10:30:28 +0200689 }
690
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100691 status = psa_key_derivation_set_capacity(derivation, capacity);
692 if (status != PSA_SUCCESS) {
693 return status;
694 }
k-stachowiak81053a52019-08-17 10:30:28 +0200695
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100696 return PSA_SUCCESS;
k-stachowiak81053a52019-08-17 10:30:28 +0200697}
698
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +0200699MBEDTLS_CHECK_RETURN_CRITICAL
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100700static int tls_prf_generic(mbedtls_md_type_t md_type,
701 const unsigned char *secret, size_t slen,
702 const char *label,
703 const unsigned char *random, size_t rlen,
704 unsigned char *dstbuf, size_t dlen)
Andrzej Kurekc929a822019-01-14 03:51:11 -0500705{
706 psa_status_t status;
707 psa_algorithm_t alg;
Ronald Croncf56a0a2020-08-04 09:51:30 +0200708 psa_key_id_t master_key = MBEDTLS_SVC_KEY_ID_INIT;
Janos Follathda6ac012019-08-16 13:47:29 +0100709 psa_key_derivation_operation_t derivation =
Janos Follath8dee8772019-07-30 12:53:32 +0100710 PSA_KEY_DERIVATION_OPERATION_INIT;
Andrzej Kurekc929a822019-01-14 03:51:11 -0500711
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100712 if (md_type == MBEDTLS_MD_SHA384) {
Andrzej Kurekc929a822019-01-14 03:51:11 -0500713 alg = PSA_ALG_TLS12_PRF(PSA_ALG_SHA_384);
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100714 } else {
Andrzej Kurekc929a822019-01-14 03:51:11 -0500715 alg = PSA_ALG_TLS12_PRF(PSA_ALG_SHA_256);
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100716 }
Andrzej Kurekc929a822019-01-14 03:51:11 -0500717
Gilles Peskine311f54d2019-09-23 18:19:22 +0200718 /* Normally a "secret" should be long enough to be impossible to
719 * find by brute force, and in particular should not be empty. But
720 * this PRF is also used to derive an IV, in particular in EAP-TLS,
721 * and for this use case it makes sense to have a 0-length "secret".
722 * Since the key API doesn't allow importing a key of length 0,
Ronald Croncf56a0a2020-08-04 09:51:30 +0200723 * keep master_key=0, which setup_psa_key_derivation() understands
Gilles Peskine311f54d2019-09-23 18:19:22 +0200724 * to mean a 0-length "secret" input. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100725 if (slen != 0) {
Gilles Peskine311f54d2019-09-23 18:19:22 +0200726 psa_key_attributes_t key_attributes = psa_key_attributes_init();
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100727 psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_DERIVE);
728 psa_set_key_algorithm(&key_attributes, alg);
729 psa_set_key_type(&key_attributes, PSA_KEY_TYPE_DERIVE);
Andrzej Kurekc929a822019-01-14 03:51:11 -0500730
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100731 status = psa_import_key(&key_attributes, secret, slen, &master_key);
732 if (status != PSA_SUCCESS) {
733 return MBEDTLS_ERR_SSL_HW_ACCEL_FAILED;
734 }
Gilles Peskine311f54d2019-09-23 18:19:22 +0200735 }
Andrzej Kurekc929a822019-01-14 03:51:11 -0500736
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100737 status = setup_psa_key_derivation(&derivation,
738 master_key, alg,
739 random, rlen,
740 (unsigned char const *) label,
741 (size_t) strlen(label),
742 dlen);
743 if (status != PSA_SUCCESS) {
744 psa_key_derivation_abort(&derivation);
745 psa_destroy_key(master_key);
746 return MBEDTLS_ERR_SSL_HW_ACCEL_FAILED;
Andrzej Kurekc929a822019-01-14 03:51:11 -0500747 }
748
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100749 status = psa_key_derivation_output_bytes(&derivation, dstbuf, dlen);
750 if (status != PSA_SUCCESS) {
751 psa_key_derivation_abort(&derivation);
752 psa_destroy_key(master_key);
753 return MBEDTLS_ERR_SSL_HW_ACCEL_FAILED;
Andrzej Kurekc929a822019-01-14 03:51:11 -0500754 }
755
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100756 status = psa_key_derivation_abort(&derivation);
757 if (status != PSA_SUCCESS) {
758 psa_destroy_key(master_key);
759 return MBEDTLS_ERR_SSL_HW_ACCEL_FAILED;
Andrzej Kurek70737ca2019-01-14 05:37:13 -0500760 }
Andrzej Kurekc929a822019-01-14 03:51:11 -0500761
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100762 if (!mbedtls_svc_key_id_is_null(master_key)) {
763 status = psa_destroy_key(master_key);
764 }
765 if (status != PSA_SUCCESS) {
766 return MBEDTLS_ERR_SSL_HW_ACCEL_FAILED;
767 }
Andrzej Kurekc929a822019-01-14 03:51:11 -0500768
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100769 return 0;
Andrzej Kurekc929a822019-01-14 03:51:11 -0500770}
771
772#else /* MBEDTLS_USE_PSA_CRYPTO */
773
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +0200774MBEDTLS_CHECK_RETURN_CRITICAL
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100775static int tls_prf_generic(mbedtls_md_type_t md_type,
776 const unsigned char *secret, size_t slen,
777 const char *label,
778 const unsigned char *random, size_t rlen,
779 unsigned char *dstbuf, size_t dlen)
Paul Bakker1ef83d62012-04-11 12:09:53 +0000780{
781 size_t nb;
Manuel Pégourié-Gonnard6890c6b2015-03-26 11:11:49 +0100782 size_t i, j, k, md_len;
Ron Eldor3b350852019-05-07 18:31:49 +0300783 unsigned char *tmp;
784 size_t tmp_len = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200785 unsigned char h_i[MBEDTLS_MD_MAX_SIZE];
786 const mbedtls_md_info_t *md_info;
787 mbedtls_md_context_t md_ctx;
Janos Follath865b3eb2019-12-16 11:46:15 +0000788 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnardb7fcca32015-03-26 11:41:28 +0100789
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100790 mbedtls_md_init(&md_ctx);
Paul Bakker1ef83d62012-04-11 12:09:53 +0000791
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100792 if ((md_info = mbedtls_md_info_from_type(md_type)) == NULL) {
793 return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
794 }
Manuel Pégourié-Gonnard6890c6b2015-03-26 11:11:49 +0100795
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100796 md_len = mbedtls_md_get_size(md_info);
Manuel Pégourié-Gonnard6890c6b2015-03-26 11:11:49 +0100797
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100798 tmp_len = md_len + strlen(label) + rlen;
799 tmp = mbedtls_calloc(1, tmp_len);
800 if (tmp == NULL) {
Ron Eldor3b350852019-05-07 18:31:49 +0300801 ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
802 goto exit;
803 }
Paul Bakker1ef83d62012-04-11 12:09:53 +0000804
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100805 nb = strlen(label);
806 memcpy(tmp + md_len, label, nb);
807 memcpy(tmp + md_len + nb, random, rlen);
Paul Bakker1ef83d62012-04-11 12:09:53 +0000808 nb += rlen;
809
810 /*
811 * Compute P_<hash>(secret, label + random)[0..dlen]
812 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100813 if ((ret = mbedtls_md_setup(&md_ctx, md_info, 1)) != 0) {
Ron Eldor3b350852019-05-07 18:31:49 +0300814 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100815 }
Manuel Pégourié-Gonnardb7fcca32015-03-26 11:41:28 +0100816
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100817 ret = mbedtls_md_hmac_starts(&md_ctx, secret, slen);
818 if (ret != 0) {
Gilles Peskine2b3f21d2021-12-10 21:35:10 +0100819 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100820 }
821 ret = mbedtls_md_hmac_update(&md_ctx, tmp + md_len, nb);
822 if (ret != 0) {
Gilles Peskine2b3f21d2021-12-10 21:35:10 +0100823 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100824 }
825 ret = mbedtls_md_hmac_finish(&md_ctx, tmp);
826 if (ret != 0) {
Gilles Peskine2b3f21d2021-12-10 21:35:10 +0100827 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100828 }
Manuel Pégourié-Gonnard7da726b2015-03-24 18:08:19 +0100829
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100830 for (i = 0; i < dlen; i += md_len) {
831 ret = mbedtls_md_hmac_reset(&md_ctx);
832 if (ret != 0) {
Gilles Peskine2b3f21d2021-12-10 21:35:10 +0100833 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100834 }
835 ret = mbedtls_md_hmac_update(&md_ctx, tmp, md_len + nb);
836 if (ret != 0) {
Gilles Peskine2b3f21d2021-12-10 21:35:10 +0100837 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100838 }
839 ret = mbedtls_md_hmac_finish(&md_ctx, h_i);
840 if (ret != 0) {
Gilles Peskine2b3f21d2021-12-10 21:35:10 +0100841 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100842 }
Manuel Pégourié-Gonnardb7fcca32015-03-26 11:41:28 +0100843
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100844 ret = mbedtls_md_hmac_reset(&md_ctx);
845 if (ret != 0) {
Gilles Peskine2b3f21d2021-12-10 21:35:10 +0100846 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100847 }
848 ret = mbedtls_md_hmac_update(&md_ctx, tmp, md_len);
849 if (ret != 0) {
Gilles Peskine2b3f21d2021-12-10 21:35:10 +0100850 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100851 }
852 ret = mbedtls_md_hmac_finish(&md_ctx, tmp);
853 if (ret != 0) {
Gilles Peskine2b3f21d2021-12-10 21:35:10 +0100854 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100855 }
Paul Bakker1ef83d62012-04-11 12:09:53 +0000856
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100857 k = (i + md_len > dlen) ? dlen % md_len : md_len;
Paul Bakker1ef83d62012-04-11 12:09:53 +0000858
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100859 for (j = 0; j < k; j++) {
Paul Bakker1ef83d62012-04-11 12:09:53 +0000860 dstbuf[i + j] = h_i[j];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100861 }
Paul Bakker1ef83d62012-04-11 12:09:53 +0000862 }
863
Ron Eldor3b350852019-05-07 18:31:49 +0300864exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100865 mbedtls_md_free(&md_ctx);
Manuel Pégourié-Gonnardb7fcca32015-03-26 11:41:28 +0100866
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100867 if (tmp != NULL) {
868 mbedtls_platform_zeroize(tmp, tmp_len);
869 }
Dave Rodgman369f4952022-11-01 16:08:14 +0000870
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100871 mbedtls_platform_zeroize(h_i, sizeof(h_i));
Paul Bakker1ef83d62012-04-11 12:09:53 +0000872
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100873 mbedtls_free(tmp);
Ron Eldor3b350852019-05-07 18:31:49 +0300874
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100875 return ret;
Paul Bakker1ef83d62012-04-11 12:09:53 +0000876}
Andrzej Kurekc929a822019-01-14 03:51:11 -0500877#endif /* MBEDTLS_USE_PSA_CRYPTO */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200878#if defined(MBEDTLS_SHA256_C)
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +0200879MBEDTLS_CHECK_RETURN_CRITICAL
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100880static int tls_prf_sha256(const unsigned char *secret, size_t slen,
881 const char *label,
882 const unsigned char *random, size_t rlen,
883 unsigned char *dstbuf, size_t dlen)
Manuel Pégourié-Gonnard6890c6b2015-03-26 11:11:49 +0100884{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100885 return tls_prf_generic(MBEDTLS_MD_SHA256, secret, slen,
886 label, random, rlen, dstbuf, dlen);
Manuel Pégourié-Gonnard6890c6b2015-03-26 11:11:49 +0100887}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200888#endif /* MBEDTLS_SHA256_C */
Paul Bakker1ef83d62012-04-11 12:09:53 +0000889
Gilles Peskined2d59372021-05-12 22:43:27 +0200890#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384)
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +0200891MBEDTLS_CHECK_RETURN_CRITICAL
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100892static int tls_prf_sha384(const unsigned char *secret, size_t slen,
893 const char *label,
894 const unsigned char *random, size_t rlen,
895 unsigned char *dstbuf, size_t dlen)
Paul Bakkerca4ab492012-04-18 14:23:57 +0000896{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100897 return tls_prf_generic(MBEDTLS_MD_SHA384, secret, slen,
898 label, random, rlen, dstbuf, dlen);
Paul Bakkerca4ab492012-04-18 14:23:57 +0000899}
Gilles Peskined2d59372021-05-12 22:43:27 +0200900#endif /* MBEDTLS_SHA512_C && !MBEDTLS_SHA512_NO_SHA384 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200901#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
Paul Bakkerca4ab492012-04-18 14:23:57 +0000902
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100903static void ssl_update_checksum_start(mbedtls_ssl_context *, const unsigned char *, size_t);
Paul Bakkerd2f068e2013-08-27 21:19:20 +0200904
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200905#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
906 defined(MBEDTLS_SSL_PROTO_TLS1_1)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100907static void ssl_update_checksum_md5sha1(mbedtls_ssl_context *, const unsigned char *, size_t);
Paul Bakkerd2f068e2013-08-27 21:19:20 +0200908#endif
Paul Bakker380da532012-04-18 16:10:25 +0000909
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200910#if defined(MBEDTLS_SSL_PROTO_SSL3)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100911static void ssl_calc_verify_ssl(const mbedtls_ssl_context *, unsigned char *, size_t *);
David Horstmann68014b22025-03-10 14:10:11 +0000912static int ssl_calc_finished_ssl(mbedtls_ssl_context *, unsigned char *, int);
Paul Bakkerd2f068e2013-08-27 21:19:20 +0200913#endif
914
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200915#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100916static void ssl_calc_verify_tls(const mbedtls_ssl_context *, unsigned char *, size_t *);
David Horstmann68014b22025-03-10 14:10:11 +0000917static int ssl_calc_finished_tls(mbedtls_ssl_context *, unsigned char *, int);
Paul Bakkerd2f068e2013-08-27 21:19:20 +0200918#endif
919
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200920#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
921#if defined(MBEDTLS_SHA256_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100922static void ssl_update_checksum_sha256(mbedtls_ssl_context *, const unsigned char *, size_t);
923static void ssl_calc_verify_tls_sha256(const mbedtls_ssl_context *, unsigned char *, size_t *);
David Horstmann68014b22025-03-10 14:10:11 +0000924static int ssl_calc_finished_tls_sha256(mbedtls_ssl_context *, unsigned char *, int);
Paul Bakkerd2f068e2013-08-27 21:19:20 +0200925#endif
Paul Bakker769075d2012-11-24 11:26:46 +0100926
Gilles Peskined2d59372021-05-12 22:43:27 +0200927#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100928static void ssl_update_checksum_sha384(mbedtls_ssl_context *, const unsigned char *, size_t);
929static void ssl_calc_verify_tls_sha384(const mbedtls_ssl_context *, unsigned char *, size_t *);
David Horstmann68014b22025-03-10 14:10:11 +0000930static int ssl_calc_finished_tls_sha384(mbedtls_ssl_context *, unsigned char *, int);
Paul Bakker769075d2012-11-24 11:26:46 +0100931#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200932#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
Paul Bakker1ef83d62012-04-11 12:09:53 +0000933
Manuel Pégourié-Gonnard45be3d82019-02-18 23:35:14 +0100934#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) && \
Hanno Becker7d0a5692018-10-23 15:26:22 +0100935 defined(MBEDTLS_USE_PSA_CRYPTO)
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +0200936MBEDTLS_CHECK_RETURN_CRITICAL
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100937static int ssl_use_opaque_psk(mbedtls_ssl_context const *ssl)
Hanno Becker7d0a5692018-10-23 15:26:22 +0100938{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100939 if (ssl->conf->f_psk != NULL) {
Hanno Becker7d0a5692018-10-23 15:26:22 +0100940 /* If we've used a callback to select the PSK,
941 * the static configuration is irrelevant. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100942 if (!mbedtls_svc_key_id_is_null(ssl->handshake->psk_opaque)) {
943 return 1;
944 }
Hanno Becker7d0a5692018-10-23 15:26:22 +0100945
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100946 return 0;
Hanno Becker7d0a5692018-10-23 15:26:22 +0100947 }
948
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100949 if (!mbedtls_svc_key_id_is_null(ssl->conf->psk_opaque)) {
950 return 1;
951 }
Hanno Becker7d0a5692018-10-23 15:26:22 +0100952
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100953 return 0;
Hanno Becker7d0a5692018-10-23 15:26:22 +0100954}
955#endif /* MBEDTLS_USE_PSA_CRYPTO &&
Manuel Pégourié-Gonnard45be3d82019-02-18 23:35:14 +0100956 MBEDTLS_KEY_EXCHANGE_PSK_ENABLED */
Hanno Becker7d0a5692018-10-23 15:26:22 +0100957
Ron Eldorcf280092019-05-14 20:19:13 +0300958#if defined(MBEDTLS_SSL_EXPORT_KEYS)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100959static mbedtls_tls_prf_types tls_prf_get_type(mbedtls_ssl_tls_prf_cb *tls_prf)
Ron Eldorcf280092019-05-14 20:19:13 +0300960{
961#if defined(MBEDTLS_SSL_PROTO_SSL3)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100962 if (tls_prf == ssl3_prf) {
963 return MBEDTLS_SSL_TLS_PRF_SSL3;
964 } else
Ron Eldorcf280092019-05-14 20:19:13 +0300965#endif
966#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100967 if (tls_prf == tls1_prf) {
968 return MBEDTLS_SSL_TLS_PRF_TLS1;
969 } else
Ron Eldorcf280092019-05-14 20:19:13 +0300970#endif
971#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
Gilles Peskined2d59372021-05-12 22:43:27 +0200972#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100973 if (tls_prf == tls_prf_sha384) {
974 return MBEDTLS_SSL_TLS_PRF_SHA384;
975 } else
Ron Eldorcf280092019-05-14 20:19:13 +0300976#endif
977#if defined(MBEDTLS_SHA256_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100978 if (tls_prf == tls_prf_sha256) {
979 return MBEDTLS_SSL_TLS_PRF_SHA256;
980 } else
Ron Eldorcf280092019-05-14 20:19:13 +0300981#endif
982#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100983 return MBEDTLS_SSL_TLS_PRF_NONE;
Ron Eldorcf280092019-05-14 20:19:13 +0300984}
985#endif /* MBEDTLS_SSL_EXPORT_KEYS */
986
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100987int mbedtls_ssl_tls_prf(const mbedtls_tls_prf_types prf,
988 const unsigned char *secret, size_t slen,
989 const char *label,
990 const unsigned char *random, size_t rlen,
991 unsigned char *dstbuf, size_t dlen)
Ron Eldor51d3ab52019-05-12 14:54:30 +0300992{
993 mbedtls_ssl_tls_prf_cb *tls_prf = NULL;
994
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100995 switch (prf) {
Ron Eldor51d3ab52019-05-12 14:54:30 +0300996#if defined(MBEDTLS_SSL_PROTO_SSL3)
997 case MBEDTLS_SSL_TLS_PRF_SSL3:
998 tls_prf = ssl3_prf;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100999 break;
Ron Eldord2f25f72019-05-15 14:54:22 +03001000#endif /* MBEDTLS_SSL_PROTO_SSL3 */
Ron Eldor51d3ab52019-05-12 14:54:30 +03001001#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1)
1002 case MBEDTLS_SSL_TLS_PRF_TLS1:
1003 tls_prf = tls1_prf;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001004 break;
Ron Eldord2f25f72019-05-15 14:54:22 +03001005#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 */
1006
1007#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
Gilles Peskined2d59372021-05-12 22:43:27 +02001008#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384)
Ron Eldor51d3ab52019-05-12 14:54:30 +03001009 case MBEDTLS_SSL_TLS_PRF_SHA384:
1010 tls_prf = tls_prf_sha384;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001011 break;
Gilles Peskined2d59372021-05-12 22:43:27 +02001012#endif /* MBEDTLS_SHA512_C && !MBEDTLS_SHA512_NO_SHA384 */
Ron Eldor51d3ab52019-05-12 14:54:30 +03001013#if defined(MBEDTLS_SHA256_C)
1014 case MBEDTLS_SSL_TLS_PRF_SHA256:
1015 tls_prf = tls_prf_sha256;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001016 break;
Ron Eldord2f25f72019-05-15 14:54:22 +03001017#endif /* MBEDTLS_SHA256_C */
1018#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001019 default:
1020 return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
Ron Eldor51d3ab52019-05-12 14:54:30 +03001021 }
1022
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001023 return tls_prf(secret, slen, label, random, rlen, dstbuf, dlen);
Ron Eldor51d3ab52019-05-12 14:54:30 +03001024}
1025
Manuel Pégourié-Gonnard9b108c22019-05-06 13:32:17 +02001026/* Type for the TLS PRF */
1027typedef int ssl_tls_prf_t(const unsigned char *, size_t, const char *,
1028 const unsigned char *, size_t,
1029 unsigned char *, size_t);
1030
Manuel Pégourié-Gonnarde59ae232019-04-30 11:41:40 +02001031/*
Manuel Pégourié-Gonnardcba40d92019-05-06 12:55:40 +02001032 * Populate a transform structure with session keys and all the other
1033 * necessary information.
Manuel Pégourié-Gonnarde59ae232019-04-30 11:41:40 +02001034 *
Manuel Pégourié-Gonnardcba40d92019-05-06 12:55:40 +02001035 * Parameters:
1036 * - [in/out]: transform: structure to populate
1037 * [in] must be just initialised with mbedtls_ssl_transform_init()
Manuel Pégourié-Gonnardc864f6a2019-05-06 13:48:22 +02001038 * [out] fully populated, ready for use by mbedtls_ssl_{en,de}crypt_buf()
Manuel Pégourié-Gonnard6fa57bf2019-05-10 10:50:04 +02001039 * - [in] ciphersuite
1040 * - [in] master
1041 * - [in] encrypt_then_mac
1042 * - [in] trunc_hmac
1043 * - [in] compression
Manuel Pégourié-Gonnard9b108c22019-05-06 13:32:17 +02001044 * - [in] tls_prf: pointer to PRF to use for key derivation
1045 * - [in] randbytes: buffer holding ServerHello.random + ClientHello.random
Manuel Pégourié-Gonnardc864f6a2019-05-06 13:48:22 +02001046 * - [in] minor_ver: SSL/TLS minor version
1047 * - [in] endpoint: client or server
1048 * - [in] ssl: optionally used for:
Manuel Pégourié-Gonnarde07bc202020-02-26 09:53:42 +01001049 * - MBEDTLS_SSL_HW_RECORD_ACCEL: whole context (non-const)
Manuel Pégourié-Gonnardc864f6a2019-05-06 13:48:22 +02001050 * - MBEDTLS_SSL_EXPORT_KEYS: ssl->conf->{f,p}_export_keys
1051 * - MBEDTLS_DEBUG_C: ssl->conf->{f,p}_dbg
Manuel Pégourié-Gonnarde59ae232019-04-30 11:41:40 +02001052 */
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +02001053MBEDTLS_CHECK_RETURN_CRITICAL
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001054static int ssl_populate_transform(mbedtls_ssl_transform *transform,
1055 int ciphersuite,
1056 const unsigned char master[48],
Jarno Lamsac84bd242019-08-16 12:06:56 +03001057#if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC)
Manuel Pégourié-Gonnard6fa57bf2019-05-10 10:50:04 +02001058#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001059 int encrypt_then_mac,
Jarno Lamsac84bd242019-08-16 12:06:56 +03001060#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
Manuel Pégourié-Gonnard6fa57bf2019-05-10 10:50:04 +02001061#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001062 int trunc_hmac,
Jarno Lamsac84bd242019-08-16 12:06:56 +03001063#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
1064#endif /* MBEDTLS_SSL_SOME_MODES_USE_MAC */
Manuel Pégourié-Gonnard6fa57bf2019-05-10 10:50:04 +02001065#if defined(MBEDTLS_ZLIB_SUPPORT)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001066 int compression,
Manuel Pégourié-Gonnard6fa57bf2019-05-10 10:50:04 +02001067#endif
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001068 ssl_tls_prf_t tls_prf,
1069 const unsigned char randbytes[64],
1070 int minor_ver,
1071 unsigned endpoint,
Manuel Pégourié-Gonnard7ae6ed42020-03-13 11:28:19 +01001072#if !defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001073 const
Manuel Pégourié-Gonnard7ae6ed42020-03-13 11:28:19 +01001074#endif
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001075 mbedtls_ssl_context *ssl)
Paul Bakker5121ce52009-01-03 21:22:43 +00001076{
Paul Bakkerda02a7f2013-08-31 17:25:14 +02001077 int ret = 0;
Hanno Beckercb1cc802018-11-17 22:27:38 +00001078#if defined(MBEDTLS_USE_PSA_CRYPTO)
1079 int psa_fallthrough;
1080#endif /* MBEDTLS_USE_PSA_CRYPTO */
David Horstmannd4f22082022-10-26 18:25:14 +01001081 int do_mbedtls_cipher_setup;
Paul Bakker5121ce52009-01-03 21:22:43 +00001082 unsigned char keyblk[256];
1083 unsigned char *key1;
1084 unsigned char *key2;
Paul Bakker68884e32013-01-07 18:20:04 +01001085 unsigned char *mac_enc;
1086 unsigned char *mac_dec;
sander-visser3888b032020-05-06 21:49:46 +02001087 size_t mac_key_len = 0;
Paul Bakkerb9cfaa02013-10-11 18:58:55 +02001088 size_t iv_copy_len;
Hanno Becker88aaf652017-12-27 08:17:40 +00001089 unsigned keylen;
Hanno Beckere694c3e2017-12-27 21:34:08 +00001090 const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001091 const mbedtls_cipher_info_t *cipher_info;
1092 const mbedtls_md_info_t *md_info;
Paul Bakker68884e32013-01-07 18:20:04 +01001093
Manuel Pégourié-Gonnardc864f6a2019-05-06 13:48:22 +02001094#if !defined(MBEDTLS_SSL_HW_RECORD_ACCEL) && \
1095 !defined(MBEDTLS_SSL_EXPORT_KEYS) && \
Gilles Peskinea6f99a12022-04-13 13:24:56 +02001096 !defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) && \
Manuel Pégourié-Gonnardc864f6a2019-05-06 13:48:22 +02001097 !defined(MBEDTLS_DEBUG_C)
Paul Elliott9c2faca2023-10-18 14:34:46 +01001098 (void) ssl; /* ssl is unused except for those cases */
Manuel Pégourié-Gonnardc864f6a2019-05-06 13:48:22 +02001099#endif
1100
Manuel Pégourié-Gonnard96fb0ee2019-07-09 12:54:17 +02001101 /*
1102 * Some data just needs copying into the structure
1103 */
Jaeden Amero2de07f12019-06-05 13:32:08 +01001104#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) && \
1105 defined(MBEDTLS_SSL_SOME_MODES_USE_MAC)
Manuel Pégourié-Gonnard6fa57bf2019-05-10 10:50:04 +02001106 transform->encrypt_then_mac = encrypt_then_mac;
Hanno Becker9eddaeb2017-12-27 21:37:21 +00001107#endif
Manuel Pégourié-Gonnardc864f6a2019-05-06 13:48:22 +02001108 transform->minor_ver = minor_ver;
Hanno Beckere694c3e2017-12-27 21:34:08 +00001109
Manuel Pégourié-Gonnard96fb0ee2019-07-09 12:54:17 +02001110#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001111 memcpy(transform->randbytes, randbytes, sizeof(transform->randbytes));
Manuel Pégourié-Gonnard96fb0ee2019-07-09 12:54:17 +02001112#endif
1113
Manuel Pégourié-Gonnard9b108c22019-05-06 13:32:17 +02001114 /*
1115 * Get various info structures
1116 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001117 ciphersuite_info = mbedtls_ssl_ciphersuite_from_id(ciphersuite);
1118 if (ciphersuite_info == NULL) {
1119 MBEDTLS_SSL_DEBUG_MSG(1, ("ciphersuite info for %d not found",
1120 ciphersuite));
1121 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
Manuel Pégourié-Gonnard9b108c22019-05-06 13:32:17 +02001122 }
1123
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001124 cipher_info = mbedtls_cipher_info_from_type(ciphersuite_info->cipher);
1125 if (cipher_info == NULL) {
1126 MBEDTLS_SSL_DEBUG_MSG(1, ("cipher info for %u not found",
1127 ciphersuite_info->cipher));
1128 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
Paul Bakker68884e32013-01-07 18:20:04 +01001129 }
1130
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001131 md_info = mbedtls_md_info_from_type(ciphersuite_info->mac);
1132 if (md_info == NULL) {
1133 MBEDTLS_SSL_DEBUG_MSG(1, ("mbedtls_md info for %u not found",
1134 (unsigned) ciphersuite_info->mac));
1135 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
Paul Bakker68884e32013-01-07 18:20:04 +01001136 }
1137
Hanno Beckera0e20d02019-05-15 14:03:01 +01001138#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
Hanno Becker4bf74652019-04-26 16:22:27 +01001139 /* Copy own and peer's CID if the use of the CID
1140 * extension has been negotiated. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001141 if (ssl->handshake->cid_in_use == MBEDTLS_SSL_CID_ENABLED) {
1142 MBEDTLS_SSL_DEBUG_MSG(3, ("Copy CIDs into SSL transform"));
Hanno Becker8a7f9722019-04-30 13:52:29 +01001143
Hanno Becker05154c32019-05-03 15:23:51 +01001144 transform->in_cid_len = ssl->own_cid_len;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001145 memcpy(transform->in_cid, ssl->own_cid, ssl->own_cid_len);
1146 MBEDTLS_SSL_DEBUG_BUF(3, "Incoming CID", transform->in_cid,
1147 transform->in_cid_len);
Hanno Beckerd1f20352019-05-15 10:21:55 +01001148
1149 transform->out_cid_len = ssl->handshake->peer_cid_len;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001150 memcpy(transform->out_cid, ssl->handshake->peer_cid,
1151 ssl->handshake->peer_cid_len);
1152 MBEDTLS_SSL_DEBUG_BUF(3, "Outgoing CID", transform->out_cid,
1153 transform->out_cid_len);
Hanno Becker4bf74652019-04-26 16:22:27 +01001154 }
Hanno Beckera0e20d02019-05-15 14:03:01 +01001155#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
Hanno Becker4bf74652019-04-26 16:22:27 +01001156
Paul Bakker5121ce52009-01-03 21:22:43 +00001157 /*
Manuel Pégourié-Gonnard9b108c22019-05-06 13:32:17 +02001158 * Compute key block using the PRF
Paul Bakker5121ce52009-01-03 21:22:43 +00001159 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001160 ret = tls_prf(master, 48, "key expansion", randbytes, 64, keyblk, 256);
1161 if (ret != 0) {
1162 MBEDTLS_SSL_DEBUG_RET(1, "prf", ret);
1163 return ret;
Manuel Pégourié-Gonnarde9608182015-03-26 11:47:47 +01001164 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001165
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001166 MBEDTLS_SSL_DEBUG_MSG(3, ("ciphersuite = %s",
1167 mbedtls_ssl_get_ciphersuite_name(ciphersuite)));
1168 MBEDTLS_SSL_DEBUG_BUF(3, "master secret", master, 48);
1169 MBEDTLS_SSL_DEBUG_BUF(4, "random bytes", randbytes, 64);
1170 MBEDTLS_SSL_DEBUG_BUF(4, "key block", keyblk, 256);
Paul Bakker5121ce52009-01-03 21:22:43 +00001171
Paul Bakker5121ce52009-01-03 21:22:43 +00001172 /*
1173 * Determine the appropriate key, IV and MAC length.
1174 */
Paul Bakker68884e32013-01-07 18:20:04 +01001175
Hanno Becker88aaf652017-12-27 08:17:40 +00001176 keylen = cipher_info->key_bitlen / 8;
Manuel Pégourié-Gonnarde800cd82014-06-18 15:34:40 +02001177
Hanno Becker8031d062018-01-03 15:32:31 +00001178#if defined(MBEDTLS_GCM_C) || \
1179 defined(MBEDTLS_CCM_C) || \
1180 defined(MBEDTLS_CHACHAPOLY_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001181 if (cipher_info->mode == MBEDTLS_MODE_GCM ||
Manuel Pégourié-Gonnard2e58e8e2018-06-18 11:16:43 +02001182 cipher_info->mode == MBEDTLS_MODE_CCM ||
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001183 cipher_info->mode == MBEDTLS_MODE_CHACHAPOLY) {
Hanno Beckerf704bef2018-11-16 15:21:18 +00001184 size_t explicit_ivlen;
Manuel Pégourié-Gonnard2e58e8e2018-06-18 11:16:43 +02001185
Manuel Pégourié-Gonnarde800cd82014-06-18 15:34:40 +02001186 transform->maclen = 0;
Hanno Becker81c7b182017-11-09 18:39:33 +00001187 mac_key_len = 0;
Hanno Beckere694c3e2017-12-27 21:34:08 +00001188 transform->taglen =
1189 ciphersuite_info->flags & MBEDTLS_CIPHERSUITE_SHORT_TAG ? 8 : 16;
Manuel Pégourié-Gonnarde800cd82014-06-18 15:34:40 +02001190
Hanno Becker447558d2020-05-28 07:36:33 +01001191 /* All modes haves 96-bit IVs, but the length of the static parts vary
1192 * with mode and version:
1193 * - For GCM and CCM in TLS 1.2, there's a static IV of 4 Bytes
1194 * (to be concatenated with a dynamically chosen IV of 8 Bytes)
Hanno Beckerf93c2d72020-05-28 07:39:43 +01001195 * - For ChaChaPoly in TLS 1.2, and all modes in TLS 1.3, there's
1196 * a static IV of 12 Bytes (to be XOR'ed with the 8 Byte record
1197 * sequence number).
Manuel Pégourié-Gonnard2e58e8e2018-06-18 11:16:43 +02001198 */
Paul Bakker68884e32013-01-07 18:20:04 +01001199 transform->ivlen = 12;
Hanno Beckerf93c2d72020-05-28 07:39:43 +01001200#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001201 if (minor_ver == MBEDTLS_SSL_MINOR_VERSION_4) {
Manuel Pégourié-Gonnard2e58e8e2018-06-18 11:16:43 +02001202 transform->fixed_ivlen = 12;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001203 } else
Hanno Beckerf93c2d72020-05-28 07:39:43 +01001204#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
1205 {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001206 if (cipher_info->mode == MBEDTLS_MODE_CHACHAPOLY) {
Hanno Beckerf93c2d72020-05-28 07:39:43 +01001207 transform->fixed_ivlen = 12;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001208 } else {
Hanno Beckerf93c2d72020-05-28 07:39:43 +01001209 transform->fixed_ivlen = 4;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001210 }
Hanno Beckerf93c2d72020-05-28 07:39:43 +01001211 }
Manuel Pégourié-Gonnarde800cd82014-06-18 15:34:40 +02001212
Manuel Pégourié-Gonnard2e58e8e2018-06-18 11:16:43 +02001213 /* Minimum length of encrypted record */
1214 explicit_ivlen = transform->ivlen - transform->fixed_ivlen;
Hanno Beckere694c3e2017-12-27 21:34:08 +00001215 transform->minlen = explicit_ivlen + transform->taglen;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001216 } else
Hanno Becker8031d062018-01-03 15:32:31 +00001217#endif /* MBEDTLS_GCM_C || MBEDTLS_CCM_C || MBEDTLS_CHACHAPOLY_C */
1218#if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001219 if (cipher_info->mode == MBEDTLS_MODE_STREAM ||
1220 cipher_info->mode == MBEDTLS_MODE_CBC) {
Manuel Pégourié-Gonnarde800cd82014-06-18 15:34:40 +02001221 /* Initialize HMAC contexts */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001222 if ((ret = mbedtls_md_setup(&transform->md_ctx_enc, md_info, 1)) != 0 ||
1223 (ret = mbedtls_md_setup(&transform->md_ctx_dec, md_info, 1)) != 0) {
1224 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_md_setup", ret);
Ron Eldore6992702019-05-07 18:27:13 +03001225 goto end;
Paul Bakker68884e32013-01-07 18:20:04 +01001226 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001227
Manuel Pégourié-Gonnarde800cd82014-06-18 15:34:40 +02001228 /* Get MAC length */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001229 mac_key_len = mbedtls_md_get_size(md_info);
Hanno Becker81c7b182017-11-09 18:39:33 +00001230 transform->maclen = mac_key_len;
Manuel Pégourié-Gonnarde800cd82014-06-18 15:34:40 +02001231
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001232#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
Manuel Pégourié-Gonnarde800cd82014-06-18 15:34:40 +02001233 /*
1234 * If HMAC is to be truncated, we shall keep the leftmost bytes,
1235 * (rfc 6066 page 13 or rfc 2104 section 4),
1236 * so we only need to adjust the length here.
1237 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001238 if (trunc_hmac == MBEDTLS_SSL_TRUNC_HMAC_ENABLED) {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001239 transform->maclen = MBEDTLS_SSL_TRUNCATED_HMAC_LEN;
Hanno Beckere89353a2017-11-20 16:36:41 +00001240
1241#if defined(MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT)
1242 /* Fall back to old, non-compliant version of the truncated
Hanno Becker563423f2017-11-21 17:20:17 +00001243 * HMAC implementation which also truncates the key
1244 * (Mbed TLS versions from 1.3 to 2.6.0) */
Hanno Beckere89353a2017-11-20 16:36:41 +00001245 mac_key_len = transform->maclen;
1246#endif
1247 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001248#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
Manuel Pégourié-Gonnarde800cd82014-06-18 15:34:40 +02001249
1250 /* IV length */
Paul Bakker68884e32013-01-07 18:20:04 +01001251 transform->ivlen = cipher_info->iv_size;
Paul Bakker5121ce52009-01-03 21:22:43 +00001252
Manuel Pégourié-Gonnardeaa76f72014-06-18 16:06:02 +02001253 /* Minimum length */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001254 if (cipher_info->mode == MBEDTLS_MODE_STREAM) {
Manuel Pégourié-Gonnardeaa76f72014-06-18 16:06:02 +02001255 transform->minlen = transform->maclen;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001256 } else {
Manuel Pégourié-Gonnardeaa76f72014-06-18 16:06:02 +02001257 /*
1258 * GenericBlockCipher:
Manuel Pégourié-Gonnard169dd6a2014-11-04 16:15:39 +01001259 * 1. if EtM is in use: one block plus MAC
1260 * otherwise: * first multiple of blocklen greater than maclen
1261 * 2. IV except for SSL3 and TLS 1.0
Manuel Pégourié-Gonnardeaa76f72014-06-18 16:06:02 +02001262 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001263#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001264 if (encrypt_then_mac == MBEDTLS_SSL_ETM_ENABLED) {
Manuel Pégourié-Gonnard169dd6a2014-11-04 16:15:39 +01001265 transform->minlen = transform->maclen
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001266 + cipher_info->block_size;
1267 } else
Manuel Pégourié-Gonnard169dd6a2014-11-04 16:15:39 +01001268#endif
1269 {
1270 transform->minlen = transform->maclen
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001271 + cipher_info->block_size
1272 - transform->maclen % cipher_info->block_size;
Manuel Pégourié-Gonnard169dd6a2014-11-04 16:15:39 +01001273 }
Manuel Pégourié-Gonnardeaa76f72014-06-18 16:06:02 +02001274
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001275#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001276 if (minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ||
1277 minor_ver == MBEDTLS_SSL_MINOR_VERSION_1) {
Manuel Pégourié-Gonnardeaa76f72014-06-18 16:06:02 +02001278 ; /* No need to adjust minlen */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001279 } else
Manuel Pégourié-Gonnardeaa76f72014-06-18 16:06:02 +02001280#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001281#if defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001282 if (minor_ver == MBEDTLS_SSL_MINOR_VERSION_2 ||
1283 minor_ver == MBEDTLS_SSL_MINOR_VERSION_3) {
Manuel Pégourié-Gonnardeaa76f72014-06-18 16:06:02 +02001284 transform->minlen += transform->ivlen;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001285 } else
Manuel Pégourié-Gonnardeaa76f72014-06-18 16:06:02 +02001286#endif
1287 {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001288 MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
Ron Eldore6992702019-05-07 18:27:13 +03001289 ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR;
1290 goto end;
Manuel Pégourié-Gonnardeaa76f72014-06-18 16:06:02 +02001291 }
Paul Bakker68884e32013-01-07 18:20:04 +01001292 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001293 } else
Hanno Becker8031d062018-01-03 15:32:31 +00001294#endif /* MBEDTLS_SSL_SOME_MODES_USE_MAC */
1295 {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001296 MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
1297 return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
Hanno Becker8031d062018-01-03 15:32:31 +00001298 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001299
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001300 MBEDTLS_SSL_DEBUG_MSG(3, ("keylen: %u, minlen: %u, ivlen: %u, maclen: %u",
1301 (unsigned) keylen,
1302 (unsigned) transform->minlen,
1303 (unsigned) transform->ivlen,
1304 (unsigned) transform->maclen));
Paul Bakker5121ce52009-01-03 21:22:43 +00001305
1306 /*
1307 * Finally setup the cipher contexts, IVs and MAC secrets.
1308 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001309#if defined(MBEDTLS_SSL_CLI_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001310 if (endpoint == MBEDTLS_SSL_IS_CLIENT) {
Hanno Becker81c7b182017-11-09 18:39:33 +00001311 key1 = keyblk + mac_key_len * 2;
Hanno Becker88aaf652017-12-27 08:17:40 +00001312 key2 = keyblk + mac_key_len * 2 + keylen;
Paul Bakker5121ce52009-01-03 21:22:43 +00001313
Paul Bakker68884e32013-01-07 18:20:04 +01001314 mac_enc = keyblk;
Hanno Becker81c7b182017-11-09 18:39:33 +00001315 mac_dec = keyblk + mac_key_len;
Paul Bakker5121ce52009-01-03 21:22:43 +00001316
Paul Bakker2e11f7d2010-07-25 14:24:53 +00001317 /*
1318 * This is not used in TLS v1.1.
1319 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001320 iv_copy_len = (transform->fixed_ivlen) ?
1321 transform->fixed_ivlen : transform->ivlen;
1322 memcpy(transform->iv_enc, key2 + keylen, iv_copy_len);
1323 memcpy(transform->iv_dec, key2 + keylen + iv_copy_len,
1324 iv_copy_len);
1325 } else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001326#endif /* MBEDTLS_SSL_CLI_C */
1327#if defined(MBEDTLS_SSL_SRV_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001328 if (endpoint == MBEDTLS_SSL_IS_SERVER) {
Hanno Becker88aaf652017-12-27 08:17:40 +00001329 key1 = keyblk + mac_key_len * 2 + keylen;
Hanno Becker81c7b182017-11-09 18:39:33 +00001330 key2 = keyblk + mac_key_len * 2;
Paul Bakker5121ce52009-01-03 21:22:43 +00001331
Hanno Becker81c7b182017-11-09 18:39:33 +00001332 mac_enc = keyblk + mac_key_len;
Paul Bakker68884e32013-01-07 18:20:04 +01001333 mac_dec = keyblk;
Paul Bakker5121ce52009-01-03 21:22:43 +00001334
Paul Bakker2e11f7d2010-07-25 14:24:53 +00001335 /*
1336 * This is not used in TLS v1.1.
1337 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001338 iv_copy_len = (transform->fixed_ivlen) ?
1339 transform->fixed_ivlen : transform->ivlen;
1340 memcpy(transform->iv_dec, key1 + keylen, iv_copy_len);
1341 memcpy(transform->iv_enc, key1 + keylen + iv_copy_len,
1342 iv_copy_len);
1343 } else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001344#endif /* MBEDTLS_SSL_SRV_C */
Manuel Pégourié-Gonnardd16d1cb2014-11-20 18:15:05 +01001345 {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001346 MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
Ron Eldore6992702019-05-07 18:27:13 +03001347 ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR;
1348 goto end;
Manuel Pégourié-Gonnardd16d1cb2014-11-20 18:15:05 +01001349 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001350
Hanno Beckerd56ed242018-01-03 15:32:51 +00001351#if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001352#if defined(MBEDTLS_SSL_PROTO_SSL3)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001353 if (minor_ver == MBEDTLS_SSL_MINOR_VERSION_0) {
1354 if (mac_key_len > sizeof(transform->mac_enc)) {
1355 MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
Ron Eldore6992702019-05-07 18:27:13 +03001356 ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR;
1357 goto end;
Manuel Pégourié-Gonnard7cfdcb82014-01-18 18:22:55 +01001358 }
1359
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001360 memcpy(transform->mac_enc, mac_enc, mac_key_len);
1361 memcpy(transform->mac_dec, mac_dec, mac_key_len);
1362 } else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001363#endif /* MBEDTLS_SSL_PROTO_SSL3 */
1364#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
1365 defined(MBEDTLS_SSL_PROTO_TLS1_2)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001366 if (minor_ver >= MBEDTLS_SSL_MINOR_VERSION_1) {
Gilles Peskine039fd122018-03-19 19:06:08 +01001367 /* For HMAC-based ciphersuites, initialize the HMAC transforms.
1368 For AEAD-based ciphersuites, there is nothing to do here. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001369 if (mac_key_len != 0) {
1370 ret = mbedtls_md_hmac_starts(&transform->md_ctx_enc,
1371 mac_enc, mac_key_len);
1372 if (ret != 0) {
Gilles Peskine2b3f21d2021-12-10 21:35:10 +01001373 goto end;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001374 }
1375 ret = mbedtls_md_hmac_starts(&transform->md_ctx_dec,
1376 mac_dec, mac_key_len);
1377 if (ret != 0) {
Gilles Peskine2b3f21d2021-12-10 21:35:10 +01001378 goto end;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001379 }
Gilles Peskine039fd122018-03-19 19:06:08 +01001380 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001381 } else
Paul Bakkerd2f068e2013-08-27 21:19:20 +02001382#endif
Paul Bakker577e0062013-08-28 11:57:20 +02001383 {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001384 MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
Ron Eldore6992702019-05-07 18:27:13 +03001385 ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR;
1386 goto end;
Paul Bakker577e0062013-08-28 11:57:20 +02001387 }
Hanno Beckerd56ed242018-01-03 15:32:51 +00001388#endif /* MBEDTLS_SSL_SOME_MODES_USE_MAC */
Paul Bakker68884e32013-01-07 18:20:04 +01001389
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001390#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001391 if (mbedtls_ssl_hw_record_init != NULL) {
sander-visser1abe8ee2020-05-06 21:27:14 +02001392 ret = 0;
Paul Bakker05ef8352012-05-08 09:17:57 +00001393
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001394 MBEDTLS_SSL_DEBUG_MSG(2, ("going for mbedtls_ssl_hw_record_init()"));
Paul Bakker05ef8352012-05-08 09:17:57 +00001395
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001396 if ((ret = mbedtls_ssl_hw_record_init(ssl, key1, key2, keylen,
1397 transform->iv_enc, transform->iv_dec,
1398 iv_copy_len,
1399 mac_enc, mac_dec,
1400 mac_key_len)) != 0) {
1401 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_hw_record_init", ret);
Ron Eldore6992702019-05-07 18:27:13 +03001402 ret = MBEDTLS_ERR_SSL_HW_ACCEL_FAILED;
1403 goto end;
Paul Bakker05ef8352012-05-08 09:17:57 +00001404 }
1405 }
Hanno Beckerd56ed242018-01-03 15:32:51 +00001406#else
1407 ((void) mac_dec);
1408 ((void) mac_enc);
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001409#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */
Paul Bakker05ef8352012-05-08 09:17:57 +00001410
Manuel Pégourié-Gonnard024b6df2015-10-19 13:52:53 +02001411#if defined(MBEDTLS_SSL_EXPORT_KEYS)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001412 if (ssl->conf->f_export_keys != NULL) {
1413 ssl->conf->f_export_keys(ssl->conf->p_export_keys,
1414 master, keyblk,
1415 mac_key_len, keylen,
1416 iv_copy_len);
Robert Cragie4feb7ae2015-10-02 13:33:37 +01001417 }
Ron Eldorf5cc10d2019-05-07 18:33:40 +03001418
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001419 if (ssl->conf->f_export_keys_ext != NULL) {
1420 ssl->conf->f_export_keys_ext(ssl->conf->p_export_keys,
1421 master, keyblk,
1422 mac_key_len, keylen,
1423 iv_copy_len,
1424 randbytes + 32,
1425 randbytes,
1426 tls_prf_get_type(tls_prf));
Ron Eldorf5cc10d2019-05-07 18:33:40 +03001427 }
Robert Cragie4feb7ae2015-10-02 13:33:37 +01001428#endif
1429
David Horstmannd4f22082022-10-26 18:25:14 +01001430 do_mbedtls_cipher_setup = 1;
Hanno Beckerf704bef2018-11-16 15:21:18 +00001431#if defined(MBEDTLS_USE_PSA_CRYPTO)
Hanno Beckercb1cc802018-11-17 22:27:38 +00001432
1433 /* Only use PSA-based ciphers for TLS-1.2.
1434 * That's relevant at least for TLS-1.0, where
1435 * we assume that mbedtls_cipher_crypt() updates
1436 * the structure field for the IV, which the PSA-based
1437 * implementation currently doesn't. */
1438#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001439 if (minor_ver == MBEDTLS_SSL_MINOR_VERSION_3) {
1440 ret = mbedtls_cipher_setup_psa(&transform->cipher_ctx_enc,
1441 cipher_info, transform->taglen);
1442 if (ret != 0 && ret != MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE) {
1443 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_cipher_setup_psa", ret);
Ron Eldore6992702019-05-07 18:27:13 +03001444 goto end;
Hanno Beckercb1cc802018-11-17 22:27:38 +00001445 }
1446
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001447 if (ret == 0) {
1448 MBEDTLS_SSL_DEBUG_MSG(3, ("Successfully setup PSA-based encryption cipher context"));
Hanno Beckercb1cc802018-11-17 22:27:38 +00001449 psa_fallthrough = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001450 } else {
1451 MBEDTLS_SSL_DEBUG_MSG(1,
1452 (
1453 "Failed to setup PSA-based cipher context for record encryption - fall through to default setup."));
Hanno Beckercb1cc802018-11-17 22:27:38 +00001454 psa_fallthrough = 1;
1455 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001456 } else {
Hanno Beckercb1cc802018-11-17 22:27:38 +00001457 psa_fallthrough = 1;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001458 }
Hanno Beckercb1cc802018-11-17 22:27:38 +00001459#else
1460 psa_fallthrough = 1;
1461#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
Hanno Beckerf704bef2018-11-16 15:21:18 +00001462
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001463 if (psa_fallthrough == 0) {
David Horstmannd4f22082022-10-26 18:25:14 +01001464 do_mbedtls_cipher_setup = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001465 }
Hanno Beckerf704bef2018-11-16 15:21:18 +00001466#endif /* MBEDTLS_USE_PSA_CRYPTO */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001467 if (do_mbedtls_cipher_setup &&
1468 (ret = mbedtls_cipher_setup(&transform->cipher_ctx_enc,
1469 cipher_info)) != 0) {
1470 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_cipher_setup", ret);
Ron Eldore6992702019-05-07 18:27:13 +03001471 goto end;
Manuel Pégourié-Gonnard88665912013-10-25 18:42:44 +02001472 }
Paul Bakkerda02a7f2013-08-31 17:25:14 +02001473
David Horstmannd4f22082022-10-26 18:25:14 +01001474 do_mbedtls_cipher_setup = 1;
Hanno Beckerf704bef2018-11-16 15:21:18 +00001475#if defined(MBEDTLS_USE_PSA_CRYPTO)
Hanno Beckercb1cc802018-11-17 22:27:38 +00001476 /* Only use PSA-based ciphers for TLS-1.2.
1477 * That's relevant at least for TLS-1.0, where
1478 * we assume that mbedtls_cipher_crypt() updates
1479 * the structure field for the IV, which the PSA-based
1480 * implementation currently doesn't. */
1481#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001482 if (minor_ver == MBEDTLS_SSL_MINOR_VERSION_3) {
1483 ret = mbedtls_cipher_setup_psa(&transform->cipher_ctx_dec,
1484 cipher_info, transform->taglen);
1485 if (ret != 0 && ret != MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE) {
1486 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_cipher_setup_psa", ret);
Ron Eldore6992702019-05-07 18:27:13 +03001487 goto end;
Hanno Beckercb1cc802018-11-17 22:27:38 +00001488 }
1489
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001490 if (ret == 0) {
1491 MBEDTLS_SSL_DEBUG_MSG(3, ("Successfully setup PSA-based decryption cipher context"));
Hanno Beckercb1cc802018-11-17 22:27:38 +00001492 psa_fallthrough = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001493 } else {
1494 MBEDTLS_SSL_DEBUG_MSG(1,
1495 (
1496 "Failed to setup PSA-based cipher context for record decryption - fall through to default setup."));
Hanno Beckercb1cc802018-11-17 22:27:38 +00001497 psa_fallthrough = 1;
1498 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001499 } else {
Hanno Beckercb1cc802018-11-17 22:27:38 +00001500 psa_fallthrough = 1;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001501 }
Hanno Beckercb1cc802018-11-17 22:27:38 +00001502#else
1503 psa_fallthrough = 1;
1504#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
Hanno Beckerf704bef2018-11-16 15:21:18 +00001505
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001506 if (psa_fallthrough == 0) {
David Horstmannd4f22082022-10-26 18:25:14 +01001507 do_mbedtls_cipher_setup = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001508 }
Hanno Beckerf704bef2018-11-16 15:21:18 +00001509#endif /* MBEDTLS_USE_PSA_CRYPTO */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001510 if (do_mbedtls_cipher_setup &&
1511 (ret = mbedtls_cipher_setup(&transform->cipher_ctx_dec,
1512 cipher_info)) != 0) {
1513 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_cipher_setup", ret);
Ron Eldore6992702019-05-07 18:27:13 +03001514 goto end;
Manuel Pégourié-Gonnard88665912013-10-25 18:42:44 +02001515 }
Paul Bakkerda02a7f2013-08-31 17:25:14 +02001516
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001517 if ((ret = mbedtls_cipher_setkey(&transform->cipher_ctx_enc, key1,
1518 cipher_info->key_bitlen,
1519 MBEDTLS_ENCRYPT)) != 0) {
1520 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_cipher_setkey", ret);
Ron Eldore6992702019-05-07 18:27:13 +03001521 goto end;
Manuel Pégourié-Gonnard88665912013-10-25 18:42:44 +02001522 }
Paul Bakkerea6ad3f2013-09-02 14:57:01 +02001523
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001524 if ((ret = mbedtls_cipher_setkey(&transform->cipher_ctx_dec, key2,
1525 cipher_info->key_bitlen,
1526 MBEDTLS_DECRYPT)) != 0) {
1527 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_cipher_setkey", ret);
Ron Eldore6992702019-05-07 18:27:13 +03001528 goto end;
Manuel Pégourié-Gonnard88665912013-10-25 18:42:44 +02001529 }
Paul Bakkerda02a7f2013-08-31 17:25:14 +02001530
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001531#if defined(MBEDTLS_CIPHER_MODE_CBC)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001532 if (cipher_info->mode == MBEDTLS_MODE_CBC) {
1533 if ((ret = mbedtls_cipher_set_padding_mode(&transform->cipher_ctx_enc,
1534 MBEDTLS_PADDING_NONE)) != 0) {
1535 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_cipher_set_padding_mode", ret);
Ron Eldore6992702019-05-07 18:27:13 +03001536 goto end;
Manuel Pégourié-Gonnard126a66f2013-10-25 18:33:32 +02001537 }
Manuel Pégourié-Gonnard88665912013-10-25 18:42:44 +02001538
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001539 if ((ret = mbedtls_cipher_set_padding_mode(&transform->cipher_ctx_dec,
1540 MBEDTLS_PADDING_NONE)) != 0) {
1541 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_cipher_set_padding_mode", ret);
Ron Eldore6992702019-05-07 18:27:13 +03001542 goto end;
Manuel Pégourié-Gonnard88665912013-10-25 18:42:44 +02001543 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001544 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001545#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001546
Paul Bakker5121ce52009-01-03 21:22:43 +00001547
Manuel Pégourié-Gonnardd73b47f2019-05-06 12:44:24 +02001548 /* Initialize Zlib contexts */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001549#if defined(MBEDTLS_ZLIB_SUPPORT)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001550 if (compression == MBEDTLS_SSL_COMPRESS_DEFLATE) {
1551 MBEDTLS_SSL_DEBUG_MSG(3, ("Initializing zlib states"));
Paul Bakker2770fbd2012-07-03 13:30:23 +00001552
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001553 memset(&transform->ctx_deflate, 0, sizeof(transform->ctx_deflate));
1554 memset(&transform->ctx_inflate, 0, sizeof(transform->ctx_inflate));
Paul Bakker2770fbd2012-07-03 13:30:23 +00001555
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001556 if (deflateInit(&transform->ctx_deflate,
1557 Z_DEFAULT_COMPRESSION) != Z_OK ||
1558 inflateInit(&transform->ctx_inflate) != Z_OK) {
1559 MBEDTLS_SSL_DEBUG_MSG(1, ("Failed to initialize compression"));
Ron Eldore6992702019-05-07 18:27:13 +03001560 ret = MBEDTLS_ERR_SSL_COMPRESSION_FAILED;
1561 goto end;
Paul Bakker2770fbd2012-07-03 13:30:23 +00001562 }
1563 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001564#endif /* MBEDTLS_ZLIB_SUPPORT */
Paul Bakker2770fbd2012-07-03 13:30:23 +00001565
Ron Eldore6992702019-05-07 18:27:13 +03001566end:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001567 mbedtls_platform_zeroize(keyblk, sizeof(keyblk));
1568 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001569}
1570
Manuel Pégourié-Gonnard8d2805c2019-04-30 12:08:59 +02001571/*
Manuel Pégourié-Gonnard47e33e12019-05-20 10:10:17 +02001572 * Set appropriate PRF function and other SSL / TLS 1.0/1.1 / TLS1.2 functions
Manuel Pégourié-Gonnard8d2805c2019-04-30 12:08:59 +02001573 *
1574 * Inputs:
1575 * - SSL/TLS minor version
1576 * - hash associated with the ciphersuite (only used by TLS 1.2)
1577 *
Manuel Pégourié-Gonnard31d3ef12019-05-10 10:25:00 +02001578 * Outputs:
Manuel Pégourié-Gonnard8d2805c2019-04-30 12:08:59 +02001579 * - the tls_prf, calc_verify and calc_finished members of handshake structure
1580 */
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +02001581MBEDTLS_CHECK_RETURN_CRITICAL
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001582static int ssl_set_handshake_prfs(mbedtls_ssl_handshake_params *handshake,
1583 int minor_ver,
1584 mbedtls_md_type_t hash)
Manuel Pégourié-Gonnard1b00c4f2019-04-30 11:54:22 +02001585{
Gilles Peskinefc9c07f2021-05-12 22:51:53 +02001586#if !defined(MBEDTLS_SSL_PROTO_TLS1_2) || \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001587 !(defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384))
Manuel Pégourié-Gonnard8d2805c2019-04-30 12:08:59 +02001588 (void) hash;
1589#endif
Manuel Pégourié-Gonnard1b00c4f2019-04-30 11:54:22 +02001590
Manuel Pégourié-Gonnard1b00c4f2019-04-30 11:54:22 +02001591#if defined(MBEDTLS_SSL_PROTO_SSL3)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001592 if (minor_ver == MBEDTLS_SSL_MINOR_VERSION_0) {
Manuel Pégourié-Gonnard1b00c4f2019-04-30 11:54:22 +02001593 handshake->tls_prf = ssl3_prf;
1594 handshake->calc_verify = ssl_calc_verify_ssl;
1595 handshake->calc_finished = ssl_calc_finished_ssl;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001596 } else
Manuel Pégourié-Gonnard1b00c4f2019-04-30 11:54:22 +02001597#endif
1598#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001599 if (minor_ver < MBEDTLS_SSL_MINOR_VERSION_3) {
Manuel Pégourié-Gonnard1b00c4f2019-04-30 11:54:22 +02001600 handshake->tls_prf = tls1_prf;
1601 handshake->calc_verify = ssl_calc_verify_tls;
1602 handshake->calc_finished = ssl_calc_finished_tls;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001603 } else
Manuel Pégourié-Gonnard1b00c4f2019-04-30 11:54:22 +02001604#endif
1605#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
Gilles Peskined2d59372021-05-12 22:43:27 +02001606#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001607 if (minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 &&
1608 hash == MBEDTLS_MD_SHA384) {
Manuel Pégourié-Gonnard1b00c4f2019-04-30 11:54:22 +02001609 handshake->tls_prf = tls_prf_sha384;
1610 handshake->calc_verify = ssl_calc_verify_tls_sha384;
1611 handshake->calc_finished = ssl_calc_finished_tls_sha384;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001612 } else
Manuel Pégourié-Gonnard1b00c4f2019-04-30 11:54:22 +02001613#endif
1614#if defined(MBEDTLS_SHA256_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001615 if (minor_ver == MBEDTLS_SSL_MINOR_VERSION_3) {
Manuel Pégourié-Gonnard1b00c4f2019-04-30 11:54:22 +02001616 handshake->tls_prf = tls_prf_sha256;
1617 handshake->calc_verify = ssl_calc_verify_tls_sha256;
1618 handshake->calc_finished = ssl_calc_finished_tls_sha256;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001619 } else
Manuel Pégourié-Gonnard1b00c4f2019-04-30 11:54:22 +02001620#endif
1621#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
1622 {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001623 return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
Manuel Pégourié-Gonnard1b00c4f2019-04-30 11:54:22 +02001624 }
1625
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001626 return 0;
Manuel Pégourié-Gonnard1b00c4f2019-04-30 11:54:22 +02001627}
1628
Manuel Pégourié-Gonnard9951b712019-04-30 12:08:59 +02001629/*
Manuel Pégourié-Gonnard85680c42019-05-03 09:16:16 +02001630 * Compute master secret if needed
Manuel Pégourié-Gonnardde047ad2019-05-03 09:46:14 +02001631 *
1632 * Parameters:
1633 * [in/out] handshake
1634 * [in] resume, premaster, extended_ms, calc_verify, tls_prf
Manuel Pégourié-Gonnardde718b92019-05-03 11:43:28 +02001635 * (PSA-PSK) ciphersuite_info, psk_opaque
Manuel Pégourié-Gonnardde047ad2019-05-03 09:46:14 +02001636 * [out] premaster (cleared)
Manuel Pégourié-Gonnardde047ad2019-05-03 09:46:14 +02001637 * [out] master
1638 * [in] ssl: optionally used for debugging, EMS and PSA-PSK
1639 * debug: conf->f_dbg, conf->p_dbg
1640 * EMS: passed to calc_verify (debug + (SSL3) session_negotiate)
Manuel Pégourié-Gonnardde718b92019-05-03 11:43:28 +02001641 * PSA-PSA: minor_ver, conf
Manuel Pégourié-Gonnard9951b712019-04-30 12:08:59 +02001642 */
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +02001643MBEDTLS_CHECK_RETURN_CRITICAL
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001644static int ssl_compute_master(mbedtls_ssl_handshake_params *handshake,
1645 unsigned char *master,
1646 const mbedtls_ssl_context *ssl)
Manuel Pégourié-Gonnard9951b712019-04-30 12:08:59 +02001647{
Janos Follath865b3eb2019-12-16 11:46:15 +00001648 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard9951b712019-04-30 12:08:59 +02001649
1650 /* cf. RFC 5246, Section 8.1:
1651 * "The master secret is always exactly 48 bytes in length." */
1652 size_t const master_secret_len = 48;
1653
1654#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
1655 unsigned char session_hash[48];
1656#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */
1657
Manuel Pégourié-Gonnard85680c42019-05-03 09:16:16 +02001658 /* The label for the KDF used for key expansion.
1659 * This is either "master secret" or "extended master secret"
1660 * depending on whether the Extended Master Secret extension
1661 * is used. */
1662 char const *lbl = "master secret";
1663
1664 /* The salt for the KDF used for key expansion.
1665 * - If the Extended Master Secret extension is not used,
1666 * this is ClientHello.Random + ServerHello.Random
1667 * (see Sect. 8.1 in RFC 5246).
1668 * - If the Extended Master Secret extension is used,
1669 * this is the transcript of the handshake so far.
1670 * (see Sect. 4 in RFC 7627). */
1671 unsigned char const *salt = handshake->randbytes;
1672 size_t salt_len = 64;
1673
Manuel Pégourié-Gonnardde047ad2019-05-03 09:46:14 +02001674#if !defined(MBEDTLS_DEBUG_C) && \
1675 !defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) && \
1676 !(defined(MBEDTLS_USE_PSA_CRYPTO) && \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001677 defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED))
Manuel Pégourié-Gonnarda7505d12019-05-07 10:17:56 +02001678 ssl = NULL; /* make sure we don't use it except for those cases */
Manuel Pégourié-Gonnardde047ad2019-05-03 09:46:14 +02001679 (void) ssl;
1680#endif
Manuel Pégourié-Gonnardde047ad2019-05-03 09:46:14 +02001681
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001682 if (handshake->resume != 0) {
1683 MBEDTLS_SSL_DEBUG_MSG(3, ("no premaster (session resumed)"));
1684 return 0;
Manuel Pégourié-Gonnard9951b712019-04-30 12:08:59 +02001685 }
Manuel Pégourié-Gonnard9951b712019-04-30 12:08:59 +02001686
1687#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001688 if (handshake->extended_ms == MBEDTLS_SSL_EXTENDED_MS_ENABLED) {
Manuel Pégourié-Gonnard85680c42019-05-03 09:16:16 +02001689 lbl = "extended master secret";
1690 salt = session_hash;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001691 handshake->calc_verify(ssl, session_hash, &salt_len);
Manuel Pégourié-Gonnard85680c42019-05-03 09:16:16 +02001692
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001693 MBEDTLS_SSL_DEBUG_BUF(3, "session hash for extended master secret",
1694 session_hash, salt_len);
Manuel Pégourié-Gonnard85680c42019-05-03 09:16:16 +02001695 }
Manuel Pégourié-Gonnard9951b712019-04-30 12:08:59 +02001696#endif /* MBEDTLS_SSL_EXTENDED_MS_ENABLED */
1697
1698#if defined(MBEDTLS_USE_PSA_CRYPTO) && \
Manuel Pégourié-Gonnardde047ad2019-05-03 09:46:14 +02001699 defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001700 if (handshake->ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK &&
Manuel Pégourié-Gonnardde718b92019-05-03 11:43:28 +02001701 ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 &&
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001702 ssl_use_opaque_psk(ssl) == 1) {
Manuel Pégourié-Gonnard85680c42019-05-03 09:16:16 +02001703 /* Perform PSK-to-MS expansion in a single step. */
1704 psa_status_t status;
1705 psa_algorithm_t alg;
Ronald Croncf56a0a2020-08-04 09:51:30 +02001706 psa_key_id_t psk;
Manuel Pégourié-Gonnard85680c42019-05-03 09:16:16 +02001707 psa_key_derivation_operation_t derivation =
1708 PSA_KEY_DERIVATION_OPERATION_INIT;
Manuel Pégourié-Gonnardde718b92019-05-03 11:43:28 +02001709 mbedtls_md_type_t hash_alg = handshake->ciphersuite_info->mac;
Manuel Pégourié-Gonnard9951b712019-04-30 12:08:59 +02001710
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001711 MBEDTLS_SSL_DEBUG_MSG(2, ("perform PSA-based PSK-to-MS expansion"));
Manuel Pégourié-Gonnard9951b712019-04-30 12:08:59 +02001712
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001713 psk = mbedtls_ssl_get_opaque_psk(ssl);
Manuel Pégourié-Gonnard9951b712019-04-30 12:08:59 +02001714
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001715 if (hash_alg == MBEDTLS_MD_SHA384) {
Manuel Pégourié-Gonnard85680c42019-05-03 09:16:16 +02001716 alg = PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA_384);
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001717 } else {
Manuel Pégourié-Gonnard85680c42019-05-03 09:16:16 +02001718 alg = PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA_256);
Manuel Pégourié-Gonnard9951b712019-04-30 12:08:59 +02001719 }
Manuel Pégourié-Gonnard85680c42019-05-03 09:16:16 +02001720
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001721 status = setup_psa_key_derivation(&derivation, psk, alg,
1722 salt, salt_len,
1723 (unsigned char const *) lbl,
1724 (size_t) strlen(lbl),
1725 master_secret_len);
1726 if (status != PSA_SUCCESS) {
1727 psa_key_derivation_abort(&derivation);
1728 return MBEDTLS_ERR_SSL_HW_ACCEL_FAILED;
Manuel Pégourié-Gonnard85680c42019-05-03 09:16:16 +02001729 }
1730
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001731 status = psa_key_derivation_output_bytes(&derivation,
1732 master,
1733 master_secret_len);
1734 if (status != PSA_SUCCESS) {
1735 psa_key_derivation_abort(&derivation);
1736 return MBEDTLS_ERR_SSL_HW_ACCEL_FAILED;
1737 }
1738
1739 status = psa_key_derivation_abort(&derivation);
1740 if (status != PSA_SUCCESS) {
1741 return MBEDTLS_ERR_SSL_HW_ACCEL_FAILED;
1742 }
1743 } else
Manuel Pégourié-Gonnard85680c42019-05-03 09:16:16 +02001744#endif
1745 {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001746 ret = handshake->tls_prf(handshake->premaster, handshake->pmslen,
1747 lbl, salt, salt_len,
1748 master,
1749 master_secret_len);
1750 if (ret != 0) {
1751 MBEDTLS_SSL_DEBUG_RET(1, "prf", ret);
1752 return ret;
Manuel Pégourié-Gonnard85680c42019-05-03 09:16:16 +02001753 }
1754
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001755 MBEDTLS_SSL_DEBUG_BUF(3, "premaster secret",
1756 handshake->premaster,
1757 handshake->pmslen);
Manuel Pégourié-Gonnard85680c42019-05-03 09:16:16 +02001758
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001759 mbedtls_platform_zeroize(handshake->premaster,
1760 sizeof(handshake->premaster));
Manuel Pégourié-Gonnard9951b712019-04-30 12:08:59 +02001761 }
1762
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001763 return 0;
Manuel Pégourié-Gonnard9951b712019-04-30 12:08:59 +02001764}
Manuel Pégourié-Gonnard1b00c4f2019-04-30 11:54:22 +02001765
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001766int mbedtls_ssl_derive_keys(mbedtls_ssl_context *ssl)
Manuel Pégourié-Gonnarde59ae232019-04-30 11:41:40 +02001767{
Janos Follath865b3eb2019-12-16 11:46:15 +00001768 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard8d2805c2019-04-30 12:08:59 +02001769 const mbedtls_ssl_ciphersuite_t * const ciphersuite_info =
1770 ssl->handshake->ciphersuite_info;
Manuel Pégourié-Gonnard1b00c4f2019-04-30 11:54:22 +02001771
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001772 MBEDTLS_SSL_DEBUG_MSG(2, ("=> derive keys"));
Manuel Pégourié-Gonnard040a9512019-05-06 12:05:58 +02001773
1774 /* Set PRF, calc_verify and calc_finished function pointers */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001775 ret = ssl_set_handshake_prfs(ssl->handshake,
1776 ssl->minor_ver,
1777 ciphersuite_info->mac);
1778 if (ret != 0) {
1779 MBEDTLS_SSL_DEBUG_RET(1, "ssl_set_handshake_prfs", ret);
1780 return ret;
Manuel Pégourié-Gonnard8d2805c2019-04-30 12:08:59 +02001781 }
Manuel Pégourié-Gonnard1b00c4f2019-04-30 11:54:22 +02001782
Manuel Pégourié-Gonnard040a9512019-05-06 12:05:58 +02001783 /* Compute master secret if needed */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001784 ret = ssl_compute_master(ssl->handshake,
1785 ssl->session_negotiate->master,
1786 ssl);
1787 if (ret != 0) {
1788 MBEDTLS_SSL_DEBUG_RET(1, "ssl_compute_master", ret);
1789 return ret;
Manuel Pégourié-Gonnard9951b712019-04-30 12:08:59 +02001790 }
1791
Manuel Pégourié-Gonnard040a9512019-05-06 12:05:58 +02001792 /* Swap the client and server random values:
1793 * - MS derivation wanted client+server (RFC 5246 8.1)
1794 * - key derivation wants server+client (RFC 5246 6.3) */
1795 {
1796 unsigned char tmp[64];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001797 memcpy(tmp, ssl->handshake->randbytes, 64);
1798 memcpy(ssl->handshake->randbytes, tmp + 32, 32);
1799 memcpy(ssl->handshake->randbytes + 32, tmp, 32);
1800 mbedtls_platform_zeroize(tmp, sizeof(tmp));
Manuel Pégourié-Gonnard040a9512019-05-06 12:05:58 +02001801 }
1802
1803 /* Populate transform structure */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001804 ret = ssl_populate_transform(ssl->transform_negotiate,
1805 ssl->session_negotiate->ciphersuite,
1806 ssl->session_negotiate->master,
Jarno Lamsac84bd242019-08-16 12:06:56 +03001807#if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC)
Manuel Pégourié-Gonnard6fa57bf2019-05-10 10:50:04 +02001808#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001809 ssl->session_negotiate->encrypt_then_mac,
Jarno Lamsac84bd242019-08-16 12:06:56 +03001810#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
Manuel Pégourié-Gonnard6fa57bf2019-05-10 10:50:04 +02001811#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001812 ssl->session_negotiate->trunc_hmac,
Jarno Lamsac84bd242019-08-16 12:06:56 +03001813#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
1814#endif /* MBEDTLS_SSL_SOME_MODES_USE_MAC */
Manuel Pégourié-Gonnard6fa57bf2019-05-10 10:50:04 +02001815#if defined(MBEDTLS_ZLIB_SUPPORT)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001816 ssl->session_negotiate->compression,
Manuel Pégourié-Gonnard6fa57bf2019-05-10 10:50:04 +02001817#endif
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001818 ssl->handshake->tls_prf,
1819 ssl->handshake->randbytes,
1820 ssl->minor_ver,
1821 ssl->conf->endpoint,
1822 ssl);
1823 if (ret != 0) {
1824 MBEDTLS_SSL_DEBUG_RET(1, "ssl_populate_transform", ret);
1825 return ret;
Manuel Pégourié-Gonnard040a9512019-05-06 12:05:58 +02001826 }
1827
1828 /* We no longer need Server/ClientHello.random values */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001829 mbedtls_platform_zeroize(ssl->handshake->randbytes,
1830 sizeof(ssl->handshake->randbytes));
Manuel Pégourié-Gonnard040a9512019-05-06 12:05:58 +02001831
Manuel Pégourié-Gonnardd73b47f2019-05-06 12:44:24 +02001832 /* Allocate compression buffer */
1833#if defined(MBEDTLS_ZLIB_SUPPORT)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001834 if (ssl->session_negotiate->compression == MBEDTLS_SSL_COMPRESS_DEFLATE &&
1835 ssl->compress_buf == NULL) {
1836 MBEDTLS_SSL_DEBUG_MSG(3, ("Allocating compression buffer"));
1837 ssl->compress_buf = mbedtls_calloc(1, MBEDTLS_SSL_COMPRESS_BUFFER_LEN);
1838 if (ssl->compress_buf == NULL) {
1839 MBEDTLS_SSL_DEBUG_MSG(1, ("alloc(%d bytes) failed",
1840 MBEDTLS_SSL_COMPRESS_BUFFER_LEN));
1841 return MBEDTLS_ERR_SSL_ALLOC_FAILED;
Manuel Pégourié-Gonnardd73b47f2019-05-06 12:44:24 +02001842 }
1843 }
1844#endif
1845
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001846 MBEDTLS_SSL_DEBUG_MSG(2, ("<= derive keys"));
Manuel Pégourié-Gonnard040a9512019-05-06 12:05:58 +02001847
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001848 return 0;
Manuel Pégourié-Gonnarde59ae232019-04-30 11:41:40 +02001849}
1850
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001851#if defined(MBEDTLS_SSL_PROTO_SSL3)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001852void ssl_calc_verify_ssl(const mbedtls_ssl_context *ssl,
1853 unsigned char *hash,
1854 size_t *hlen)
Paul Bakker5121ce52009-01-03 21:22:43 +00001855{
Manuel Pégourié-Gonnardc0bf01e2015-07-06 16:11:18 +02001856 mbedtls_md5_context md5;
1857 mbedtls_sha1_context sha1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001858 unsigned char pad_1[48];
1859 unsigned char pad_2[48];
1860
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001861 MBEDTLS_SSL_DEBUG_MSG(2, ("=> calc verify ssl"));
Paul Bakker5121ce52009-01-03 21:22:43 +00001862
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001863 mbedtls_md5_init(&md5);
1864 mbedtls_sha1_init(&sha1);
Manuel Pégourié-Gonnard001f2b62015-07-06 16:21:13 +02001865
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001866 mbedtls_md5_clone(&md5, &ssl->handshake->fin_md5);
1867 mbedtls_sha1_clone(&sha1, &ssl->handshake->fin_sha1);
Paul Bakker5121ce52009-01-03 21:22:43 +00001868
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001869 memset(pad_1, 0x36, 48);
1870 memset(pad_2, 0x5C, 48);
Paul Bakker5121ce52009-01-03 21:22:43 +00001871
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001872 mbedtls_md5_update_ret(&md5, ssl->session_negotiate->master, 48);
1873 mbedtls_md5_update_ret(&md5, pad_1, 48);
1874 mbedtls_md5_finish_ret(&md5, hash);
Paul Bakker5121ce52009-01-03 21:22:43 +00001875
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001876 mbedtls_md5_starts_ret(&md5);
1877 mbedtls_md5_update_ret(&md5, ssl->session_negotiate->master, 48);
1878 mbedtls_md5_update_ret(&md5, pad_2, 48);
1879 mbedtls_md5_update_ret(&md5, hash, 16);
1880 mbedtls_md5_finish_ret(&md5, hash);
Paul Bakker5121ce52009-01-03 21:22:43 +00001881
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001882 mbedtls_sha1_update_ret(&sha1, ssl->session_negotiate->master, 48);
1883 mbedtls_sha1_update_ret(&sha1, pad_1, 40);
1884 mbedtls_sha1_finish_ret(&sha1, hash + 16);
Paul Bakker380da532012-04-18 16:10:25 +00001885
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001886 mbedtls_sha1_starts_ret(&sha1);
1887 mbedtls_sha1_update_ret(&sha1, ssl->session_negotiate->master, 48);
1888 mbedtls_sha1_update_ret(&sha1, pad_2, 40);
1889 mbedtls_sha1_update_ret(&sha1, hash + 16, 20);
1890 mbedtls_sha1_finish_ret(&sha1, hash + 16);
Paul Bakker380da532012-04-18 16:10:25 +00001891
Manuel Pégourié-Gonnardde718b92019-05-03 11:43:28 +02001892 *hlen = 36;
1893
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001894 MBEDTLS_SSL_DEBUG_BUF(3, "calculated verify result", hash, *hlen);
1895 MBEDTLS_SSL_DEBUG_MSG(2, ("<= calc verify"));
Paul Bakker380da532012-04-18 16:10:25 +00001896
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001897 mbedtls_md5_free(&md5);
1898 mbedtls_sha1_free(&sha1);
Paul Bakker5b4af392014-06-26 12:09:34 +02001899
Paul Bakker380da532012-04-18 16:10:25 +00001900 return;
1901}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001902#endif /* MBEDTLS_SSL_PROTO_SSL3 */
Paul Bakker380da532012-04-18 16:10:25 +00001903
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001904#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001905void ssl_calc_verify_tls(const mbedtls_ssl_context *ssl,
1906 unsigned char *hash,
1907 size_t *hlen)
Paul Bakker380da532012-04-18 16:10:25 +00001908{
Manuel Pégourié-Gonnardc0bf01e2015-07-06 16:11:18 +02001909 mbedtls_md5_context md5;
1910 mbedtls_sha1_context sha1;
Paul Bakker380da532012-04-18 16:10:25 +00001911
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001912 MBEDTLS_SSL_DEBUG_MSG(2, ("=> calc verify tls"));
Paul Bakker380da532012-04-18 16:10:25 +00001913
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001914 mbedtls_md5_init(&md5);
1915 mbedtls_sha1_init(&sha1);
Manuel Pégourié-Gonnard001f2b62015-07-06 16:21:13 +02001916
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001917 mbedtls_md5_clone(&md5, &ssl->handshake->fin_md5);
1918 mbedtls_sha1_clone(&sha1, &ssl->handshake->fin_sha1);
Paul Bakker380da532012-04-18 16:10:25 +00001919
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001920 mbedtls_md5_finish_ret(&md5, hash);
1921 mbedtls_sha1_finish_ret(&sha1, hash + 16);
Paul Bakker380da532012-04-18 16:10:25 +00001922
Manuel Pégourié-Gonnardde718b92019-05-03 11:43:28 +02001923 *hlen = 36;
1924
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001925 MBEDTLS_SSL_DEBUG_BUF(3, "calculated verify result", hash, *hlen);
1926 MBEDTLS_SSL_DEBUG_MSG(2, ("<= calc verify"));
Paul Bakker380da532012-04-18 16:10:25 +00001927
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001928 mbedtls_md5_free(&md5);
1929 mbedtls_sha1_free(&sha1);
Paul Bakker5b4af392014-06-26 12:09:34 +02001930
Paul Bakker380da532012-04-18 16:10:25 +00001931 return;
1932}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001933#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 */
Paul Bakker380da532012-04-18 16:10:25 +00001934
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001935#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
1936#if defined(MBEDTLS_SHA256_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001937void ssl_calc_verify_tls_sha256(const mbedtls_ssl_context *ssl,
1938 unsigned char *hash,
1939 size_t *hlen)
Paul Bakker380da532012-04-18 16:10:25 +00001940{
Andrzej Kurekeb342242019-01-29 09:14:33 -05001941#if defined(MBEDTLS_USE_PSA_CRYPTO)
1942 size_t hash_size;
1943 psa_status_t status;
1944 psa_hash_operation_t sha256_psa = psa_hash_operation_init();
1945
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001946 MBEDTLS_SSL_DEBUG_MSG(2, ("=> PSA calc verify sha256"));
1947 status = psa_hash_clone(&ssl->handshake->fin_sha256_psa, &sha256_psa);
1948 if (status != PSA_SUCCESS) {
1949 MBEDTLS_SSL_DEBUG_MSG(2, ("PSA hash clone failed"));
Andrzej Kurekeb342242019-01-29 09:14:33 -05001950 return;
1951 }
1952
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001953 status = psa_hash_finish(&sha256_psa, hash, 32, &hash_size);
1954 if (status != PSA_SUCCESS) {
1955 MBEDTLS_SSL_DEBUG_MSG(2, ("PSA hash finish failed"));
Andrzej Kurekeb342242019-01-29 09:14:33 -05001956 return;
1957 }
Manuel Pégourié-Gonnardde718b92019-05-03 11:43:28 +02001958
1959 *hlen = 32;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001960 MBEDTLS_SSL_DEBUG_BUF(3, "PSA calculated verify result", hash, *hlen);
1961 MBEDTLS_SSL_DEBUG_MSG(2, ("<= PSA calc verify"));
Andrzej Kurekeb342242019-01-29 09:14:33 -05001962#else
Manuel Pégourié-Gonnardc0bf01e2015-07-06 16:11:18 +02001963 mbedtls_sha256_context sha256;
Paul Bakker380da532012-04-18 16:10:25 +00001964
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001965 mbedtls_sha256_init(&sha256);
Manuel Pégourié-Gonnard001f2b62015-07-06 16:21:13 +02001966
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001967 MBEDTLS_SSL_DEBUG_MSG(2, ("=> calc verify sha256"));
Paul Bakker380da532012-04-18 16:10:25 +00001968
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001969 mbedtls_sha256_clone(&sha256, &ssl->handshake->fin_sha256);
1970 mbedtls_sha256_finish_ret(&sha256, hash);
Paul Bakker380da532012-04-18 16:10:25 +00001971
Manuel Pégourié-Gonnardde718b92019-05-03 11:43:28 +02001972 *hlen = 32;
1973
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001974 MBEDTLS_SSL_DEBUG_BUF(3, "calculated verify result", hash, *hlen);
1975 MBEDTLS_SSL_DEBUG_MSG(2, ("<= calc verify"));
Paul Bakker380da532012-04-18 16:10:25 +00001976
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001977 mbedtls_sha256_free(&sha256);
Andrzej Kurekeb342242019-01-29 09:14:33 -05001978#endif /* MBEDTLS_USE_PSA_CRYPTO */
Paul Bakker380da532012-04-18 16:10:25 +00001979 return;
1980}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001981#endif /* MBEDTLS_SHA256_C */
Paul Bakker380da532012-04-18 16:10:25 +00001982
Gilles Peskined2d59372021-05-12 22:43:27 +02001983#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001984void ssl_calc_verify_tls_sha384(const mbedtls_ssl_context *ssl,
1985 unsigned char *hash,
1986 size_t *hlen)
Paul Bakker380da532012-04-18 16:10:25 +00001987{
Andrzej Kurekeb342242019-01-29 09:14:33 -05001988#if defined(MBEDTLS_USE_PSA_CRYPTO)
1989 size_t hash_size;
1990 psa_status_t status;
Andrzej Kurek972fba52019-01-30 03:29:12 -05001991 psa_hash_operation_t sha384_psa = psa_hash_operation_init();
Andrzej Kurekeb342242019-01-29 09:14:33 -05001992
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001993 MBEDTLS_SSL_DEBUG_MSG(2, ("=> PSA calc verify sha384"));
1994 status = psa_hash_clone(&ssl->handshake->fin_sha384_psa, &sha384_psa);
1995 if (status != PSA_SUCCESS) {
1996 MBEDTLS_SSL_DEBUG_MSG(2, ("PSA hash clone failed"));
Andrzej Kurekeb342242019-01-29 09:14:33 -05001997 return;
1998 }
1999
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002000 status = psa_hash_finish(&sha384_psa, hash, 48, &hash_size);
2001 if (status != PSA_SUCCESS) {
2002 MBEDTLS_SSL_DEBUG_MSG(2, ("PSA hash finish failed"));
Andrzej Kurekeb342242019-01-29 09:14:33 -05002003 return;
2004 }
Manuel Pégourié-Gonnardde718b92019-05-03 11:43:28 +02002005
2006 *hlen = 48;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002007 MBEDTLS_SSL_DEBUG_BUF(3, "PSA calculated verify result", hash, *hlen);
2008 MBEDTLS_SSL_DEBUG_MSG(2, ("<= PSA calc verify"));
Andrzej Kurekeb342242019-01-29 09:14:33 -05002009#else
Manuel Pégourié-Gonnardc0bf01e2015-07-06 16:11:18 +02002010 mbedtls_sha512_context sha512;
Paul Bakker380da532012-04-18 16:10:25 +00002011
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002012 mbedtls_sha512_init(&sha512);
Manuel Pégourié-Gonnard001f2b62015-07-06 16:21:13 +02002013
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002014 MBEDTLS_SSL_DEBUG_MSG(2, ("=> calc verify sha384"));
Paul Bakker380da532012-04-18 16:10:25 +00002015
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002016 mbedtls_sha512_clone(&sha512, &ssl->handshake->fin_sha512);
2017 mbedtls_sha512_finish_ret(&sha512, hash);
Paul Bakker5121ce52009-01-03 21:22:43 +00002018
Manuel Pégourié-Gonnardde718b92019-05-03 11:43:28 +02002019 *hlen = 48;
2020
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002021 MBEDTLS_SSL_DEBUG_BUF(3, "calculated verify result", hash, *hlen);
2022 MBEDTLS_SSL_DEBUG_MSG(2, ("<= calc verify"));
Paul Bakker5121ce52009-01-03 21:22:43 +00002023
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002024 mbedtls_sha512_free(&sha512);
Andrzej Kurekeb342242019-01-29 09:14:33 -05002025#endif /* MBEDTLS_USE_PSA_CRYPTO */
Paul Bakker5121ce52009-01-03 21:22:43 +00002026 return;
2027}
Gilles Peskined2d59372021-05-12 22:43:27 +02002028#endif /* MBEDTLS_SHA512_C && !MBEDTLS_SHA512_NO_SHA384 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002029#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
Paul Bakker5121ce52009-01-03 21:22:43 +00002030
Gilles Peskineeccd8882020-03-10 12:19:08 +01002031#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002032int mbedtls_ssl_psk_derive_premaster(mbedtls_ssl_context *ssl, mbedtls_key_exchange_type_t key_ex)
Manuel Pégourié-Gonnardbd1ae242013-10-14 13:09:25 +02002033{
Manuel Pégourié-Gonnardbd1ae242013-10-14 13:09:25 +02002034 unsigned char *p = ssl->handshake->premaster;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002035 unsigned char *end = p + sizeof(ssl->handshake->premaster);
Guilhem Bryantb5f04e42020-04-01 11:23:58 +01002036 const unsigned char *psk = NULL;
Guilhem Bryant61b0fe62020-03-27 11:12:12 +00002037 size_t psk_len = 0;
Manuel Pégourié-Gonnard4b682962015-05-07 15:59:54 +01002038
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002039 if (mbedtls_ssl_get_psk(ssl, &psk, &psk_len)
2040 == MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED) {
Guilhem Bryantc5285d82020-03-25 17:08:15 +00002041 /*
2042 * This should never happen because the existence of a PSK is always
2043 * checked before calling this function
2044 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002045 MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
2046 return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
Manuel Pégourié-Gonnard4b682962015-05-07 15:59:54 +01002047 }
Manuel Pégourié-Gonnardbd1ae242013-10-14 13:09:25 +02002048
2049 /*
2050 * PMS = struct {
2051 * opaque other_secret<0..2^16-1>;
2052 * opaque psk<0..2^16-1>;
2053 * };
2054 * with "other_secret" depending on the particular key exchange
2055 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002056#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002057 if (key_ex == MBEDTLS_KEY_EXCHANGE_PSK) {
2058 if (end - p < 2) {
2059 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
2060 }
Manuel Pégourié-Gonnardbd1ae242013-10-14 13:09:25 +02002061
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002062 MBEDTLS_PUT_UINT16_BE(psk_len, p, 0);
Joe Subbiania651e6f2021-08-23 11:35:25 +01002063 p += 2;
Manuel Pégourié-Gonnardbc5e5082015-10-21 12:35:29 +02002064
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002065 if (end < p || (size_t) (end - p) < psk_len) {
2066 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
2067 }
Manuel Pégourié-Gonnardbc5e5082015-10-21 12:35:29 +02002068
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002069 memset(p, 0, psk_len);
Manuel Pégourié-Gonnard4b682962015-05-07 15:59:54 +01002070 p += psk_len;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002071 } else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002072#endif /* MBEDTLS_KEY_EXCHANGE_PSK_ENABLED */
2073#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002074 if (key_ex == MBEDTLS_KEY_EXCHANGE_RSA_PSK) {
Manuel Pégourié-Gonnard0fae60b2013-10-14 17:39:48 +02002075 /*
2076 * other_secret already set by the ClientKeyExchange message,
2077 * and is 48 bytes long
2078 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002079 if (end - p < 2) {
2080 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
2081 }
Philippe Antoine747fd532018-05-30 09:13:21 +02002082
Manuel Pégourié-Gonnard0fae60b2013-10-14 17:39:48 +02002083 *p++ = 0;
2084 *p++ = 48;
2085 p += 48;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002086 } else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002087#endif /* MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */
2088#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002089 if (key_ex == MBEDTLS_KEY_EXCHANGE_DHE_PSK) {
Janos Follath865b3eb2019-12-16 11:46:15 +00002090 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard33352052015-06-02 16:17:08 +01002091 size_t len;
Manuel Pégourié-Gonnardbd1ae242013-10-14 13:09:25 +02002092
Manuel Pégourié-Gonnard8df68632014-06-23 17:56:08 +02002093 /* Write length only when we know the actual value */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002094 if ((ret = mbedtls_dhm_calc_secret(&ssl->handshake->dhm_ctx,
2095 p + 2, end - (p + 2), &len,
2096 ssl->conf->f_rng, ssl->conf->p_rng)) != 0) {
2097 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_dhm_calc_secret", ret);
2098 return ret;
Manuel Pégourié-Gonnardbd1ae242013-10-14 13:09:25 +02002099 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002100 MBEDTLS_PUT_UINT16_BE(len, p, 0);
Joe Subbiania651e6f2021-08-23 11:35:25 +01002101 p += 2 + len;
Manuel Pégourié-Gonnardbd1ae242013-10-14 13:09:25 +02002102
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002103 MBEDTLS_SSL_DEBUG_MPI(3, "DHM: K ", &ssl->handshake->dhm_ctx.K);
2104 } else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002105#endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */
2106#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002107 if (key_ex == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK) {
Janos Follath865b3eb2019-12-16 11:46:15 +00002108 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnardbd1ae242013-10-14 13:09:25 +02002109 size_t zlen;
2110
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002111 if ((ret = mbedtls_ecdh_calc_secret(&ssl->handshake->ecdh_ctx, &zlen,
2112 p + 2, end - (p + 2),
2113 ssl->conf->f_rng, ssl->conf->p_rng)) != 0) {
2114 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecdh_calc_secret", ret);
2115 return ret;
Manuel Pégourié-Gonnardbd1ae242013-10-14 13:09:25 +02002116 }
2117
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002118 MBEDTLS_PUT_UINT16_BE(zlen, p, 0);
Joe Subbiania651e6f2021-08-23 11:35:25 +01002119 p += 2 + zlen;
Manuel Pégourié-Gonnardbd1ae242013-10-14 13:09:25 +02002120
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002121 MBEDTLS_SSL_DEBUG_ECDH(3, &ssl->handshake->ecdh_ctx,
2122 MBEDTLS_DEBUG_ECDH_Z);
2123 } else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002124#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
Manuel Pégourié-Gonnardbd1ae242013-10-14 13:09:25 +02002125 {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002126 MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
2127 return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
Manuel Pégourié-Gonnardbd1ae242013-10-14 13:09:25 +02002128 }
2129
2130 /* opaque psk<0..2^16-1>; */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002131 if (end - p < 2) {
2132 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
2133 }
Manuel Pégourié-Gonnardb2bf5a12014-03-25 16:28:12 +01002134
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002135 MBEDTLS_PUT_UINT16_BE(psk_len, p, 0);
Joe Subbiania651e6f2021-08-23 11:35:25 +01002136 p += 2;
Manuel Pégourié-Gonnardbc5e5082015-10-21 12:35:29 +02002137
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002138 if (end < p || (size_t) (end - p) < psk_len) {
2139 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
2140 }
Manuel Pégourié-Gonnardbc5e5082015-10-21 12:35:29 +02002141
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002142 memcpy(p, psk, psk_len);
Manuel Pégourié-Gonnard4b682962015-05-07 15:59:54 +01002143 p += psk_len;
Manuel Pégourié-Gonnardbd1ae242013-10-14 13:09:25 +02002144
2145 ssl->handshake->pmslen = p - ssl->handshake->premaster;
2146
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002147 return 0;
Manuel Pégourié-Gonnardbd1ae242013-10-14 13:09:25 +02002148}
Gilles Peskineeccd8882020-03-10 12:19:08 +01002149#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
Manuel Pégourié-Gonnardbd1ae242013-10-14 13:09:25 +02002150
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002151#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_RENEGOTIATION)
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +02002152MBEDTLS_CHECK_RETURN_CRITICAL
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002153static int ssl_write_hello_request(mbedtls_ssl_context *ssl);
Manuel Pégourié-Gonnarddf3acd82014-10-15 15:07:45 +02002154
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002155#if defined(MBEDTLS_SSL_PROTO_DTLS)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002156int mbedtls_ssl_resend_hello_request(mbedtls_ssl_context *ssl)
Manuel Pégourié-Gonnarddf3acd82014-10-15 15:07:45 +02002157{
2158 /* If renegotiation is not enforced, retransmit until we would reach max
2159 * timeout if we were using the usual handshake doubling scheme */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002160 if (ssl->conf->renego_max_records < 0) {
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02002161 uint32_t ratio = ssl->conf->hs_timeout_max / ssl->conf->hs_timeout_min + 1;
Manuel Pégourié-Gonnarddf3acd82014-10-15 15:07:45 +02002162 unsigned char doublings = 1;
2163
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002164 while (ratio != 0) {
Manuel Pégourié-Gonnarddf3acd82014-10-15 15:07:45 +02002165 ++doublings;
2166 ratio >>= 1;
2167 }
2168
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002169 if (++ssl->renego_records_seen > doublings) {
2170 MBEDTLS_SSL_DEBUG_MSG(2, ("no longer retransmitting hello request"));
2171 return 0;
Manuel Pégourié-Gonnarddf3acd82014-10-15 15:07:45 +02002172 }
2173 }
2174
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002175 return ssl_write_hello_request(ssl);
Manuel Pégourié-Gonnarddf3acd82014-10-15 15:07:45 +02002176}
2177#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002178#endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_RENEGOTIATION */
Manuel Pégourié-Gonnard26a4cf62014-10-15 13:52:48 +02002179
Hanno Beckerb9d44792019-02-08 07:19:04 +00002180#if defined(MBEDTLS_X509_CRT_PARSE_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002181static void ssl_clear_peer_cert(mbedtls_ssl_session *session)
Hanno Beckerb9d44792019-02-08 07:19:04 +00002182{
2183#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002184 if (session->peer_cert != NULL) {
2185 mbedtls_x509_crt_free(session->peer_cert);
2186 mbedtls_free(session->peer_cert);
Hanno Beckerb9d44792019-02-08 07:19:04 +00002187 session->peer_cert = NULL;
2188 }
2189#else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002190 if (session->peer_cert_digest != NULL) {
Hanno Beckerb9d44792019-02-08 07:19:04 +00002191 /* Zeroization is not necessary. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002192 mbedtls_free(session->peer_cert_digest);
Hanno Beckerb9d44792019-02-08 07:19:04 +00002193 session->peer_cert_digest = NULL;
2194 session->peer_cert_digest_type = MBEDTLS_MD_NONE;
2195 session->peer_cert_digest_len = 0;
2196 }
2197#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
2198}
2199#endif /* MBEDTLS_X509_CRT_PARSE_C */
2200
Paul Bakker5121ce52009-01-03 21:22:43 +00002201/*
2202 * Handshake functions
2203 */
Gilles Peskineeccd8882020-03-10 12:19:08 +01002204#if !defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
Gilles Peskinef9828522017-05-03 12:28:43 +02002205/* No certificate support -> dummy functions */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002206int mbedtls_ssl_write_certificate(mbedtls_ssl_context *ssl)
Paul Bakker5121ce52009-01-03 21:22:43 +00002207{
Hanno Beckere694c3e2017-12-27 21:34:08 +00002208 const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
2209 ssl->handshake->ciphersuite_info;
Paul Bakker5121ce52009-01-03 21:22:43 +00002210
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002211 MBEDTLS_SSL_DEBUG_MSG(2, ("=> write certificate"));
Paul Bakker5121ce52009-01-03 21:22:43 +00002212
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002213 if (!mbedtls_ssl_ciphersuite_uses_srv_cert(ciphersuite_info)) {
2214 MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip write certificate"));
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02002215 ssl->state++;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002216 return 0;
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02002217 }
2218
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002219 MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
2220 return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002221}
2222
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002223int mbedtls_ssl_parse_certificate(mbedtls_ssl_context *ssl)
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002224{
Hanno Beckere694c3e2017-12-27 21:34:08 +00002225 const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
2226 ssl->handshake->ciphersuite_info;
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002227
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002228 MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse certificate"));
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002229
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002230 if (!mbedtls_ssl_ciphersuite_uses_srv_cert(ciphersuite_info)) {
2231 MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip parse certificate"));
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002232 ssl->state++;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002233 return 0;
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002234 }
2235
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002236 MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
2237 return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002238}
Gilles Peskinef9828522017-05-03 12:28:43 +02002239
Gilles Peskineeccd8882020-03-10 12:19:08 +01002240#else /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
Gilles Peskinef9828522017-05-03 12:28:43 +02002241/* Some certificate support -> implement write and parse */
2242
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002243int mbedtls_ssl_write_certificate(mbedtls_ssl_context *ssl)
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002244{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002245 int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002246 size_t i, n;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002247 const mbedtls_x509_crt *crt;
Hanno Beckere694c3e2017-12-27 21:34:08 +00002248 const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
2249 ssl->handshake->ciphersuite_info;
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002250
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002251 MBEDTLS_SSL_DEBUG_MSG(2, ("=> write certificate"));
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002252
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002253 if (!mbedtls_ssl_ciphersuite_uses_srv_cert(ciphersuite_info)) {
2254 MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip write certificate"));
Johan Pascal4f099262020-09-22 10:59:26 +02002255 ssl->state++;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002256 return 0;
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002257 }
2258
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002259#if defined(MBEDTLS_SSL_CLI_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002260 if (ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT) {
2261 if (ssl->client_auth == 0) {
2262 MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip write certificate"));
Paul Bakker5121ce52009-01-03 21:22:43 +00002263 ssl->state++;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002264 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +00002265 }
2266
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002267#if defined(MBEDTLS_SSL_PROTO_SSL3)
Paul Bakker5121ce52009-01-03 21:22:43 +00002268 /*
2269 * If using SSLv3 and got no cert, send an Alert message
2270 * (otherwise an empty Certificate message will be sent).
2271 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002272 if (mbedtls_ssl_own_cert(ssl) == NULL &&
2273 ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0) {
Paul Bakker5121ce52009-01-03 21:22:43 +00002274 ssl->out_msglen = 2;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002275 ssl->out_msgtype = MBEDTLS_SSL_MSG_ALERT;
2276 ssl->out_msg[0] = MBEDTLS_SSL_ALERT_LEVEL_WARNING;
2277 ssl->out_msg[1] = MBEDTLS_SSL_ALERT_MSG_NO_CERT;
Paul Bakker5121ce52009-01-03 21:22:43 +00002278
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002279 MBEDTLS_SSL_DEBUG_MSG(2, ("got no certificate to send"));
Paul Bakker5121ce52009-01-03 21:22:43 +00002280 goto write_msg;
2281 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002282#endif /* MBEDTLS_SSL_PROTO_SSL3 */
Paul Bakker5121ce52009-01-03 21:22:43 +00002283 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002284#endif /* MBEDTLS_SSL_CLI_C */
2285#if defined(MBEDTLS_SSL_SRV_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002286 if (ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER) {
2287 if (mbedtls_ssl_own_cert(ssl) == NULL) {
2288 MBEDTLS_SSL_DEBUG_MSG(1, ("got no certificate to send"));
2289 return MBEDTLS_ERR_SSL_CERTIFICATE_REQUIRED;
Paul Bakker5121ce52009-01-03 21:22:43 +00002290 }
2291 }
Manuel Pégourié-Gonnardd16d1cb2014-11-20 18:15:05 +01002292#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002293
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002294 MBEDTLS_SSL_DEBUG_CRT(3, "own certificate", mbedtls_ssl_own_cert(ssl));
Paul Bakker5121ce52009-01-03 21:22:43 +00002295
2296 /*
2297 * 0 . 0 handshake type
2298 * 1 . 3 handshake length
2299 * 4 . 6 length of all certs
2300 * 7 . 9 length of cert. 1
2301 * 10 . n-1 peer certificate
2302 * n . n+2 length of cert. 2
2303 * n+3 . ... upper level cert, etc.
2304 */
2305 i = 7;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002306 crt = mbedtls_ssl_own_cert(ssl);
Paul Bakker5121ce52009-01-03 21:22:43 +00002307
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002308 while (crt != NULL) {
Paul Bakker5121ce52009-01-03 21:22:43 +00002309 n = crt->raw.len;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002310 if (n > MBEDTLS_SSL_OUT_CONTENT_LEN - 3 - i) {
2311 MBEDTLS_SSL_DEBUG_MSG(1, ("certificate too large, %" MBEDTLS_PRINTF_SIZET
2312 " > %" MBEDTLS_PRINTF_SIZET,
2313 i + 3 + n, (size_t) MBEDTLS_SSL_OUT_CONTENT_LEN));
2314 return MBEDTLS_ERR_SSL_CERTIFICATE_TOO_LARGE;
Paul Bakker5121ce52009-01-03 21:22:43 +00002315 }
2316
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002317 ssl->out_msg[i] = MBEDTLS_BYTE_2(n);
2318 ssl->out_msg[i + 1] = MBEDTLS_BYTE_1(n);
2319 ssl->out_msg[i + 2] = MBEDTLS_BYTE_0(n);
Paul Bakker5121ce52009-01-03 21:22:43 +00002320
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002321 i += 3; memcpy(ssl->out_msg + i, crt->raw.p, n);
Paul Bakker5121ce52009-01-03 21:22:43 +00002322 i += n; crt = crt->next;
2323 }
2324
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002325 ssl->out_msg[4] = MBEDTLS_BYTE_2(i - 7);
2326 ssl->out_msg[5] = MBEDTLS_BYTE_1(i - 7);
2327 ssl->out_msg[6] = MBEDTLS_BYTE_0(i - 7);
Paul Bakker5121ce52009-01-03 21:22:43 +00002328
2329 ssl->out_msglen = i;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002330 ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
2331 ssl->out_msg[0] = MBEDTLS_SSL_HS_CERTIFICATE;
Paul Bakker5121ce52009-01-03 21:22:43 +00002332
Manuel Pégourié-Gonnardcf141ca2015-05-20 10:35:51 +02002333#if defined(MBEDTLS_SSL_PROTO_SSL3) && defined(MBEDTLS_SSL_CLI_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00002334write_msg:
Paul Bakkerd2f068e2013-08-27 21:19:20 +02002335#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002336
2337 ssl->state++;
2338
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002339 if ((ret = mbedtls_ssl_write_handshake_msg(ssl)) != 0) {
2340 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_handshake_msg", ret);
2341 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00002342 }
2343
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002344 MBEDTLS_SSL_DEBUG_MSG(2, ("<= write certificate"));
Paul Bakker5121ce52009-01-03 21:22:43 +00002345
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002346 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00002347}
2348
Hanno Becker84879e32019-01-31 07:44:03 +00002349#if defined(MBEDTLS_SSL_RENEGOTIATION) && defined(MBEDTLS_SSL_CLI_C)
Hanno Becker177475a2019-02-05 17:02:46 +00002350
2351#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +02002352MBEDTLS_CHECK_RETURN_CRITICAL
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002353static int ssl_check_peer_crt_unchanged(mbedtls_ssl_context *ssl,
2354 unsigned char *crt_buf,
2355 size_t crt_buf_len)
Hanno Beckerdef9bdc2019-01-30 14:46:46 +00002356{
2357 mbedtls_x509_crt const * const peer_crt = ssl->session->peer_cert;
2358
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002359 if (peer_crt == NULL) {
2360 return -1;
2361 }
Hanno Beckerdef9bdc2019-01-30 14:46:46 +00002362
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002363 if (peer_crt->raw.len != crt_buf_len) {
2364 return -1;
2365 }
Hanno Beckerdef9bdc2019-01-30 14:46:46 +00002366
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002367 return memcmp(peer_crt->raw.p, crt_buf, peer_crt->raw.len);
Hanno Beckerdef9bdc2019-01-30 14:46:46 +00002368}
Hanno Becker177475a2019-02-05 17:02:46 +00002369#else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +02002370MBEDTLS_CHECK_RETURN_CRITICAL
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002371static int ssl_check_peer_crt_unchanged(mbedtls_ssl_context *ssl,
2372 unsigned char *crt_buf,
2373 size_t crt_buf_len)
Hanno Becker177475a2019-02-05 17:02:46 +00002374{
Janos Follath865b3eb2019-12-16 11:46:15 +00002375 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Hanno Becker177475a2019-02-05 17:02:46 +00002376 unsigned char const * const peer_cert_digest =
2377 ssl->session->peer_cert_digest;
2378 mbedtls_md_type_t const peer_cert_digest_type =
2379 ssl->session->peer_cert_digest_type;
2380 mbedtls_md_info_t const * const digest_info =
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002381 mbedtls_md_info_from_type(peer_cert_digest_type);
Hanno Becker177475a2019-02-05 17:02:46 +00002382 unsigned char tmp_digest[MBEDTLS_SSL_PEER_CERT_DIGEST_MAX_LEN];
2383 size_t digest_len;
2384
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002385 if (peer_cert_digest == NULL || digest_info == NULL) {
2386 return -1;
2387 }
Hanno Becker177475a2019-02-05 17:02:46 +00002388
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002389 digest_len = mbedtls_md_get_size(digest_info);
2390 if (digest_len > MBEDTLS_SSL_PEER_CERT_DIGEST_MAX_LEN) {
2391 return -1;
2392 }
Hanno Becker177475a2019-02-05 17:02:46 +00002393
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002394 ret = mbedtls_md(digest_info, crt_buf, crt_buf_len, tmp_digest);
2395 if (ret != 0) {
2396 return -1;
2397 }
Hanno Becker177475a2019-02-05 17:02:46 +00002398
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002399 return memcmp(tmp_digest, peer_cert_digest, digest_len);
Hanno Becker177475a2019-02-05 17:02:46 +00002400}
2401#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
Hanno Becker84879e32019-01-31 07:44:03 +00002402#endif /* MBEDTLS_SSL_RENEGOTIATION && MBEDTLS_SSL_CLI_C */
Hanno Beckerdef9bdc2019-01-30 14:46:46 +00002403
Manuel Pégourié-Gonnardfed37ed2017-08-15 13:27:41 +02002404/*
2405 * Once the certificate message is read, parse it into a cert chain and
2406 * perform basic checks, but leave actual verification to the caller
2407 */
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +02002408MBEDTLS_CHECK_RETURN_CRITICAL
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002409static int ssl_parse_certificate_chain(mbedtls_ssl_context *ssl,
2410 mbedtls_x509_crt *chain)
Paul Bakker5121ce52009-01-03 21:22:43 +00002411{
Janos Follath865b3eb2019-12-16 11:46:15 +00002412 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Hanno Beckerc7bd7802019-02-05 15:37:23 +00002413#if defined(MBEDTLS_SSL_RENEGOTIATION) && defined(MBEDTLS_SSL_CLI_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002414 int crt_cnt = 0;
Hanno Beckerc7bd7802019-02-05 15:37:23 +00002415#endif
Paul Bakker23986e52011-04-24 08:57:21 +00002416 size_t i, n;
Gilles Peskine064a85c2017-05-10 10:46:40 +02002417 uint8_t alert;
Paul Bakker5121ce52009-01-03 21:22:43 +00002418
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002419 if (ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE) {
2420 MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate message"));
2421 mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
2422 MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE);
2423 return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
Paul Bakker5121ce52009-01-03 21:22:43 +00002424 }
2425
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002426 if (ssl->in_msg[0] != MBEDTLS_SSL_HS_CERTIFICATE ||
2427 ssl->in_hslen < mbedtls_ssl_hs_hdr_len(ssl) + 3 + 3) {
2428 MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate message"));
2429 mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
2430 MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
2431 return MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE;
Paul Bakker5121ce52009-01-03 21:22:43 +00002432 }
2433
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002434 i = mbedtls_ssl_hs_hdr_len(ssl);
Manuel Pégourié-Gonnardf49a7da2014-09-10 13:30:43 +00002435
Paul Bakker5121ce52009-01-03 21:22:43 +00002436 /*
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002437 * Same message structure as in mbedtls_ssl_write_certificate()
Paul Bakker5121ce52009-01-03 21:22:43 +00002438 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002439 n = (ssl->in_msg[i+1] << 8) | ssl->in_msg[i+2];
Paul Bakker5121ce52009-01-03 21:22:43 +00002440
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002441 if (ssl->in_msg[i] != 0 ||
2442 ssl->in_hslen != n + 3 + mbedtls_ssl_hs_hdr_len(ssl)) {
2443 MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate message"));
2444 mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
2445 MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
2446 return MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE;
Paul Bakker5121ce52009-01-03 21:22:43 +00002447 }
2448
Hanno Beckerdef9bdc2019-01-30 14:46:46 +00002449 /* Make &ssl->in_msg[i] point to the beginning of the CRT chain. */
2450 i += 3;
2451
Hanno Beckerdef9bdc2019-01-30 14:46:46 +00002452 /* Iterate through and parse the CRTs in the provided chain. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002453 while (i < ssl->in_hslen) {
Hanno Beckerdef9bdc2019-01-30 14:46:46 +00002454 /* Check that there's room for the next CRT's length fields. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002455 if (i + 3 > ssl->in_hslen) {
2456 MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate message"));
2457 mbedtls_ssl_send_alert_message(ssl,
2458 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
2459 MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
2460 return MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE;
Philippe Antoine747fd532018-05-30 09:13:21 +02002461 }
Hanno Beckerdef9bdc2019-01-30 14:46:46 +00002462 /* In theory, the CRT can be up to 2**24 Bytes, but we don't support
2463 * anything beyond 2**16 ~ 64K. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002464 if (ssl->in_msg[i] != 0) {
2465 MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate message"));
2466 mbedtls_ssl_send_alert_message(ssl,
2467 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
2468 MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
2469 return MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE;
Paul Bakker5121ce52009-01-03 21:22:43 +00002470 }
2471
Hanno Beckerdef9bdc2019-01-30 14:46:46 +00002472 /* Read length of the next CRT in the chain. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002473 n = ((unsigned int) ssl->in_msg[i + 1] << 8)
Paul Bakker5121ce52009-01-03 21:22:43 +00002474 | (unsigned int) ssl->in_msg[i + 2];
2475 i += 3;
2476
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002477 if (n < 128 || i + n > ssl->in_hslen) {
2478 MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate message"));
2479 mbedtls_ssl_send_alert_message(ssl,
2480 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
2481 MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
2482 return MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE;
Paul Bakker5121ce52009-01-03 21:22:43 +00002483 }
2484
Hanno Beckerdef9bdc2019-01-30 14:46:46 +00002485 /* Check if we're handling the first CRT in the chain. */
Hanno Beckerc7bd7802019-02-05 15:37:23 +00002486#if defined(MBEDTLS_SSL_RENEGOTIATION) && defined(MBEDTLS_SSL_CLI_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002487 if (crt_cnt++ == 0 &&
Hanno Beckerc7bd7802019-02-05 15:37:23 +00002488 ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT &&
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002489 ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS) {
Hanno Becker46f34d02019-02-08 14:00:04 +00002490 /* During client-side renegotiation, check that the server's
2491 * end-CRTs hasn't changed compared to the initial handshake,
2492 * mitigating the triple handshake attack. On success, reuse
2493 * the original end-CRT instead of parsing it again. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002494 MBEDTLS_SSL_DEBUG_MSG(3, ("Check that peer CRT hasn't changed during renegotiation"));
2495 if (ssl_check_peer_crt_unchanged(ssl,
2496 &ssl->in_msg[i],
2497 n) != 0) {
2498 MBEDTLS_SSL_DEBUG_MSG(1, ("new server cert during renegotiation"));
2499 mbedtls_ssl_send_alert_message(ssl,
2500 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
2501 MBEDTLS_SSL_ALERT_MSG_ACCESS_DENIED);
2502 return MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE;
Hanno Beckerdef9bdc2019-01-30 14:46:46 +00002503 }
Hanno Beckerc7bd7802019-02-05 15:37:23 +00002504
2505 /* Now we can safely free the original chain. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002506 ssl_clear_peer_cert(ssl->session);
Hanno Beckerc7bd7802019-02-05 15:37:23 +00002507 }
Hanno Beckerdef9bdc2019-01-30 14:46:46 +00002508#endif /* MBEDTLS_SSL_RENEGOTIATION && MBEDTLS_SSL_CLI_C */
2509
Hanno Beckerdef9bdc2019-01-30 14:46:46 +00002510 /* Parse the next certificate in the chain. */
Hanno Becker0056eab2019-02-08 14:39:16 +00002511#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002512 ret = mbedtls_x509_crt_parse_der(chain, ssl->in_msg + i, n);
Hanno Becker0056eab2019-02-08 14:39:16 +00002513#else
Hanno Becker353a6f02019-02-26 11:51:34 +00002514 /* If we don't need to store the CRT chain permanently, parse
Hanno Becker0056eab2019-02-08 14:39:16 +00002515 * it in-place from the input buffer instead of making a copy. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002516 ret = mbedtls_x509_crt_parse_der_nocopy(chain, ssl->in_msg + i, n);
Hanno Becker0056eab2019-02-08 14:39:16 +00002517#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002518 switch (ret) {
Hanno Beckerdef9bdc2019-01-30 14:46:46 +00002519 case 0: /*ok*/
2520 case MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG + MBEDTLS_ERR_OID_NOT_FOUND:
2521 /* Ignore certificate with an unknown algorithm: maybe a
2522 prior certificate was already trusted. */
2523 break;
Gilles Peskine1cc8e342017-05-03 16:28:34 +02002524
Hanno Beckerdef9bdc2019-01-30 14:46:46 +00002525 case MBEDTLS_ERR_X509_ALLOC_FAILED:
2526 alert = MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR;
2527 goto crt_parse_der_failed;
Gilles Peskine1cc8e342017-05-03 16:28:34 +02002528
Hanno Beckerdef9bdc2019-01-30 14:46:46 +00002529 case MBEDTLS_ERR_X509_UNKNOWN_VERSION:
2530 alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
2531 goto crt_parse_der_failed;
Gilles Peskine1cc8e342017-05-03 16:28:34 +02002532
Hanno Beckerdef9bdc2019-01-30 14:46:46 +00002533 default:
2534 alert = MBEDTLS_SSL_ALERT_MSG_BAD_CERT;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002535crt_parse_der_failed:
2536 mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, alert);
2537 MBEDTLS_SSL_DEBUG_RET(1, " mbedtls_x509_crt_parse_der", ret);
2538 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00002539 }
2540
2541 i += n;
2542 }
2543
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002544 MBEDTLS_SSL_DEBUG_CRT(3, "peer certificate", chain);
2545 return 0;
Manuel Pégourié-Gonnardfed37ed2017-08-15 13:27:41 +02002546}
2547
Hanno Becker4a55f632019-02-05 12:49:06 +00002548#if defined(MBEDTLS_SSL_SRV_C)
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +02002549MBEDTLS_CHECK_RETURN_CRITICAL
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002550static int ssl_srv_check_client_no_crt_notification(mbedtls_ssl_context *ssl)
Hanno Becker4a55f632019-02-05 12:49:06 +00002551{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002552 if (ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT) {
2553 return -1;
2554 }
Hanno Becker4a55f632019-02-05 12:49:06 +00002555
2556#if defined(MBEDTLS_SSL_PROTO_SSL3)
2557 /*
2558 * Check if the client sent an empty certificate
2559 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002560 if (ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0) {
2561 if (ssl->in_msglen == 2 &&
Hanno Becker4a55f632019-02-05 12:49:06 +00002562 ssl->in_msgtype == MBEDTLS_SSL_MSG_ALERT &&
2563 ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_WARNING &&
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002564 ssl->in_msg[1] == MBEDTLS_SSL_ALERT_MSG_NO_CERT) {
2565 MBEDTLS_SSL_DEBUG_MSG(1, ("SSLv3 client has no certificate"));
2566 return 0;
Hanno Becker4a55f632019-02-05 12:49:06 +00002567 }
2568
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002569 return -1;
Hanno Becker4a55f632019-02-05 12:49:06 +00002570 }
2571#endif /* MBEDTLS_SSL_PROTO_SSL3 */
2572
2573#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
2574 defined(MBEDTLS_SSL_PROTO_TLS1_2)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002575 if (ssl->in_hslen == 3 + mbedtls_ssl_hs_hdr_len(ssl) &&
Hanno Becker4a55f632019-02-05 12:49:06 +00002576 ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
2577 ssl->in_msg[0] == MBEDTLS_SSL_HS_CERTIFICATE &&
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002578 memcmp(ssl->in_msg + mbedtls_ssl_hs_hdr_len(ssl), "\0\0\0", 3) == 0) {
2579 MBEDTLS_SSL_DEBUG_MSG(1, ("TLSv1 client has no certificate"));
2580 return 0;
Hanno Becker4a55f632019-02-05 12:49:06 +00002581 }
2582
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002583 return -1;
Hanno Becker4a55f632019-02-05 12:49:06 +00002584#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \
2585 MBEDTLS_SSL_PROTO_TLS1_2 */
2586}
2587#endif /* MBEDTLS_SSL_SRV_C */
2588
Hanno Becker28f2fcd2019-02-07 10:11:07 +00002589/* Check if a certificate message is expected.
2590 * Return either
2591 * - SSL_CERTIFICATE_EXPECTED, or
2592 * - SSL_CERTIFICATE_SKIP
2593 * indicating whether a Certificate message is expected or not.
2594 */
2595#define SSL_CERTIFICATE_EXPECTED 0
2596#define SSL_CERTIFICATE_SKIP 1
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +02002597MBEDTLS_CHECK_RETURN_CRITICAL
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002598static int ssl_parse_certificate_coordinate(mbedtls_ssl_context *ssl,
2599 int authmode)
Hanno Becker28f2fcd2019-02-07 10:11:07 +00002600{
2601 const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
Hanno Beckere694c3e2017-12-27 21:34:08 +00002602 ssl->handshake->ciphersuite_info;
Hanno Becker28f2fcd2019-02-07 10:11:07 +00002603
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002604 if (!mbedtls_ssl_ciphersuite_uses_srv_cert(ciphersuite_info)) {
2605 return SSL_CERTIFICATE_SKIP;
2606 }
Hanno Becker28f2fcd2019-02-07 10:11:07 +00002607
2608#if defined(MBEDTLS_SSL_SRV_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002609 if (ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER) {
2610 if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK) {
2611 return SSL_CERTIFICATE_SKIP;
2612 }
Hanno Becker28f2fcd2019-02-07 10:11:07 +00002613
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002614 if (authmode == MBEDTLS_SSL_VERIFY_NONE) {
Hanno Becker28f2fcd2019-02-07 10:11:07 +00002615 ssl->session_negotiate->verify_result =
2616 MBEDTLS_X509_BADCERT_SKIP_VERIFY;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002617 return SSL_CERTIFICATE_SKIP;
Hanno Becker28f2fcd2019-02-07 10:11:07 +00002618 }
2619 }
Hanno Becker84d9d272019-03-01 08:10:46 +00002620#else
2621 ((void) authmode);
Hanno Becker28f2fcd2019-02-07 10:11:07 +00002622#endif /* MBEDTLS_SSL_SRV_C */
2623
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002624 return SSL_CERTIFICATE_EXPECTED;
Hanno Becker28f2fcd2019-02-07 10:11:07 +00002625}
2626
Gilles Peskine3a2f75d2025-02-12 23:28:48 +01002627static int get_hostname_for_verification(mbedtls_ssl_context *ssl,
2628 const char **hostname)
2629{
2630 if (!mbedtls_ssl_has_set_hostname_been_called(ssl)) {
2631 MBEDTLS_SSL_DEBUG_MSG(1, ("Certificate verification without having set hostname"));
Gilles Peskine551756d2025-02-13 14:39:02 +01002632#if !defined(MBEDTLS_SSL_CLI_ALLOW_WEAK_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME)
2633 if (ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT &&
2634 ssl->conf->authmode == MBEDTLS_SSL_VERIFY_REQUIRED) {
2635 return MBEDTLS_ERR_SSL_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME;
2636 }
2637#endif
Gilles Peskine3a2f75d2025-02-12 23:28:48 +01002638 }
2639
2640 *hostname = mbedtls_ssl_get_hostname_pointer(ssl);
2641 if (*hostname == NULL) {
2642 MBEDTLS_SSL_DEBUG_MSG(2, ("Certificate verification without CN verification"));
2643 }
2644
2645 return 0;
2646}
2647
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +02002648MBEDTLS_CHECK_RETURN_CRITICAL
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002649static int ssl_parse_certificate_verify(mbedtls_ssl_context *ssl,
2650 int authmode,
2651 mbedtls_x509_crt *chain,
2652 void *rs_ctx)
Manuel Pégourié-Gonnardfed37ed2017-08-15 13:27:41 +02002653{
Hanno Becker28f2fcd2019-02-07 10:11:07 +00002654 const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
Hanno Beckere694c3e2017-12-27 21:34:08 +00002655 ssl->handshake->ciphersuite_info;
Hanno Beckerafd0b0a2019-03-27 16:55:01 +00002656 int have_ca_chain = 0;
Hanno Becker68636192019-02-05 14:36:34 +00002657
Hanno Becker8927c832019-04-03 12:52:50 +01002658 int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *);
2659 void *p_vrfy;
2660
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002661 if (authmode == MBEDTLS_SSL_VERIFY_NONE) {
2662 return 0;
2663 }
Hanno Becker68636192019-02-05 14:36:34 +00002664
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002665 if (ssl->f_vrfy != NULL) {
2666 MBEDTLS_SSL_DEBUG_MSG(3, ("Use context-specific verification callback"));
Hanno Becker8927c832019-04-03 12:52:50 +01002667 f_vrfy = ssl->f_vrfy;
2668 p_vrfy = ssl->p_vrfy;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002669 } else {
2670 MBEDTLS_SSL_DEBUG_MSG(3, ("Use configuration-specific verification callback"));
Hanno Becker8927c832019-04-03 12:52:50 +01002671 f_vrfy = ssl->conf->f_vrfy;
2672 p_vrfy = ssl->conf->p_vrfy;
2673 }
2674
Gilles Peskine3a2f75d2025-02-12 23:28:48 +01002675 const char *hostname = "";
2676 int ret = get_hostname_for_verification(ssl, &hostname);
2677 if (ret != 0) {
2678 MBEDTLS_SSL_DEBUG_RET(1, "get_hostname_for_verification", ret);
2679 return ret;
2680 }
2681
Hanno Becker68636192019-02-05 14:36:34 +00002682 /*
2683 * Main check: verify certificate
2684 */
Hanno Beckerafd0b0a2019-03-27 16:55:01 +00002685#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002686 if (ssl->conf->f_ca_cb != NULL) {
Hanno Beckerafd0b0a2019-03-27 16:55:01 +00002687 ((void) rs_ctx);
2688 have_ca_chain = 1;
2689
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002690 MBEDTLS_SSL_DEBUG_MSG(3, ("use CA callback for X.509 CRT verification"));
Jarno Lamsa9822c0d2019-04-01 16:59:48 +03002691 ret = mbedtls_x509_crt_verify_with_ca_cb(
Hanno Beckerafd0b0a2019-03-27 16:55:01 +00002692 chain,
2693 ssl->conf->f_ca_cb,
2694 ssl->conf->p_ca_cb,
2695 ssl->conf->cert_profile,
Gilles Peskine3a2f75d2025-02-12 23:28:48 +01002696 hostname,
Hanno Beckerafd0b0a2019-03-27 16:55:01 +00002697 &ssl->session_negotiate->verify_result,
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002698 f_vrfy, p_vrfy);
2699 } else
Hanno Beckerafd0b0a2019-03-27 16:55:01 +00002700#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */
2701 {
2702 mbedtls_x509_crt *ca_chain;
2703 mbedtls_x509_crl *ca_crl;
2704
2705#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002706 if (ssl->handshake->sni_ca_chain != NULL) {
Hanno Beckerafd0b0a2019-03-27 16:55:01 +00002707 ca_chain = ssl->handshake->sni_ca_chain;
2708 ca_crl = ssl->handshake->sni_ca_crl;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002709 } else
Hanno Beckerafd0b0a2019-03-27 16:55:01 +00002710#endif
2711 {
2712 ca_chain = ssl->conf->ca_chain;
2713 ca_crl = ssl->conf->ca_crl;
2714 }
2715
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002716 if (ca_chain != NULL) {
Hanno Beckerafd0b0a2019-03-27 16:55:01 +00002717 have_ca_chain = 1;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002718 }
Hanno Beckerafd0b0a2019-03-27 16:55:01 +00002719
2720 ret = mbedtls_x509_crt_verify_restartable(
2721 chain,
2722 ca_chain, ca_crl,
2723 ssl->conf->cert_profile,
Gilles Peskine3a2f75d2025-02-12 23:28:48 +01002724 hostname,
Hanno Beckerafd0b0a2019-03-27 16:55:01 +00002725 &ssl->session_negotiate->verify_result,
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002726 f_vrfy, p_vrfy, rs_ctx);
Hanno Beckerafd0b0a2019-03-27 16:55:01 +00002727 }
Hanno Becker68636192019-02-05 14:36:34 +00002728
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002729 if (ret != 0) {
2730 MBEDTLS_SSL_DEBUG_RET(1, "x509_verify_cert", ret);
Hanno Becker68636192019-02-05 14:36:34 +00002731 }
2732
Gilles Peskineeccd8882020-03-10 12:19:08 +01002733#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002734 if (ret == MBEDTLS_ERR_ECP_IN_PROGRESS) {
2735 return MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS;
2736 }
Hanno Becker68636192019-02-05 14:36:34 +00002737#endif
2738
2739 /*
2740 * Secondary checks: always done, but change 'ret' only if it was 0
2741 */
2742
2743#if defined(MBEDTLS_ECP_C)
2744 {
2745 const mbedtls_pk_context *pk = &chain->pk;
2746
Manuel Pégourié-Gonnard06e1fcd2022-06-16 10:48:06 +02002747 /* If certificate uses an EC key, make sure the curve is OK.
2748 * This is a public key, so it can't be opaque, so can_do() is a good
2749 * enough check to ensure pk_ec() is safe to use here. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002750 if (mbedtls_pk_can_do(pk, MBEDTLS_PK_ECKEY) &&
2751 mbedtls_ssl_check_curve(ssl, mbedtls_pk_ec(*pk)->grp.id) != 0) {
Hanno Becker68636192019-02-05 14:36:34 +00002752 ssl->session_negotiate->verify_result |= MBEDTLS_X509_BADCERT_BAD_KEY;
2753
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002754 MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate (EC key curve)"));
2755 if (ret == 0) {
Hanno Becker68636192019-02-05 14:36:34 +00002756 ret = MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002757 }
Hanno Becker68636192019-02-05 14:36:34 +00002758 }
2759 }
2760#endif /* MBEDTLS_ECP_C */
2761
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002762 if (mbedtls_ssl_check_cert_usage(chain,
2763 ciphersuite_info,
2764 !ssl->conf->endpoint,
2765 &ssl->session_negotiate->verify_result) != 0) {
2766 MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate (usage extensions)"));
2767 if (ret == 0) {
Hanno Becker68636192019-02-05 14:36:34 +00002768 ret = MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002769 }
Hanno Becker68636192019-02-05 14:36:34 +00002770 }
2771
2772 /* mbedtls_x509_crt_verify_with_profile is supposed to report a
2773 * verification failure through MBEDTLS_ERR_X509_CERT_VERIFY_FAILED,
2774 * with details encoded in the verification flags. All other kinds
2775 * of error codes, including those from the user provided f_vrfy
2776 * functions, are treated as fatal and lead to a failure of
2777 * ssl_parse_certificate even if verification was optional. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002778 if (authmode == MBEDTLS_SSL_VERIFY_OPTIONAL &&
2779 (ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED ||
2780 ret == MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE)) {
Hanno Becker68636192019-02-05 14:36:34 +00002781 ret = 0;
2782 }
2783
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002784 if (have_ca_chain == 0 && authmode == MBEDTLS_SSL_VERIFY_REQUIRED) {
2785 MBEDTLS_SSL_DEBUG_MSG(1, ("got no CA chain"));
Hanno Becker68636192019-02-05 14:36:34 +00002786 ret = MBEDTLS_ERR_SSL_CA_CHAIN_REQUIRED;
2787 }
2788
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002789 if (ret != 0) {
Hanno Becker68636192019-02-05 14:36:34 +00002790 uint8_t alert;
2791
2792 /* The certificate may have been rejected for several reasons.
2793 Pick one and send the corresponding alert. Which alert to send
2794 may be a subject of debate in some cases. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002795 if (ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_OTHER) {
Hanno Becker68636192019-02-05 14:36:34 +00002796 alert = MBEDTLS_SSL_ALERT_MSG_ACCESS_DENIED;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002797 } else if (ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_CN_MISMATCH) {
Hanno Becker68636192019-02-05 14:36:34 +00002798 alert = MBEDTLS_SSL_ALERT_MSG_BAD_CERT;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002799 } else if (ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_KEY_USAGE) {
Hanno Becker68636192019-02-05 14:36:34 +00002800 alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002801 } else if (ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_EXT_KEY_USAGE) {
Hanno Becker68636192019-02-05 14:36:34 +00002802 alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002803 } else if (ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_NS_CERT_TYPE) {
Hanno Becker68636192019-02-05 14:36:34 +00002804 alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002805 } else if (ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_BAD_PK) {
Hanno Becker68636192019-02-05 14:36:34 +00002806 alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002807 } else if (ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_BAD_KEY) {
Hanno Becker68636192019-02-05 14:36:34 +00002808 alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002809 } else if (ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_EXPIRED) {
Hanno Becker68636192019-02-05 14:36:34 +00002810 alert = MBEDTLS_SSL_ALERT_MSG_CERT_EXPIRED;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002811 } else if (ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_REVOKED) {
Hanno Becker68636192019-02-05 14:36:34 +00002812 alert = MBEDTLS_SSL_ALERT_MSG_CERT_REVOKED;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002813 } else if (ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_NOT_TRUSTED) {
Hanno Becker68636192019-02-05 14:36:34 +00002814 alert = MBEDTLS_SSL_ALERT_MSG_UNKNOWN_CA;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002815 } else {
Hanno Becker68636192019-02-05 14:36:34 +00002816 alert = MBEDTLS_SSL_ALERT_MSG_CERT_UNKNOWN;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002817 }
2818 mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
2819 alert);
Hanno Becker68636192019-02-05 14:36:34 +00002820 }
2821
2822#if defined(MBEDTLS_DEBUG_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002823 if (ssl->session_negotiate->verify_result != 0) {
2824 MBEDTLS_SSL_DEBUG_MSG(3, ("! Certificate verification flags %08x",
2825 (unsigned int) ssl->session_negotiate->verify_result));
2826 } else {
2827 MBEDTLS_SSL_DEBUG_MSG(3, ("Certificate verification flags clear"));
Hanno Becker68636192019-02-05 14:36:34 +00002828 }
2829#endif /* MBEDTLS_DEBUG_C */
2830
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002831 return ret;
Hanno Becker68636192019-02-05 14:36:34 +00002832}
2833
Hanno Becker6b8fbab2019-02-08 14:59:05 +00002834#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +02002835MBEDTLS_CHECK_RETURN_CRITICAL
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002836static int ssl_remember_peer_crt_digest(mbedtls_ssl_context *ssl,
2837 unsigned char *start, size_t len)
Hanno Becker6b8fbab2019-02-08 14:59:05 +00002838{
Janos Follath865b3eb2019-12-16 11:46:15 +00002839 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Hanno Becker6b8fbab2019-02-08 14:59:05 +00002840 /* Remember digest of the peer's end-CRT. */
2841 ssl->session_negotiate->peer_cert_digest =
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002842 mbedtls_calloc(1, MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_LEN);
2843 if (ssl->session_negotiate->peer_cert_digest == NULL) {
2844 MBEDTLS_SSL_DEBUG_MSG(1, ("alloc(%d bytes) failed",
2845 MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_LEN));
2846 mbedtls_ssl_send_alert_message(ssl,
2847 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
2848 MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR);
Hanno Becker6b8fbab2019-02-08 14:59:05 +00002849
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002850 return MBEDTLS_ERR_SSL_ALLOC_FAILED;
Hanno Becker6b8fbab2019-02-08 14:59:05 +00002851 }
2852
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002853 ret = mbedtls_md(mbedtls_md_info_from_type(
2854 MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_TYPE),
2855 start, len,
2856 ssl->session_negotiate->peer_cert_digest);
Hanno Becker6b8fbab2019-02-08 14:59:05 +00002857
2858 ssl->session_negotiate->peer_cert_digest_type =
2859 MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_TYPE;
2860 ssl->session_negotiate->peer_cert_digest_len =
2861 MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_LEN;
2862
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002863 return ret;
Hanno Becker6b8fbab2019-02-08 14:59:05 +00002864}
2865
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +02002866MBEDTLS_CHECK_RETURN_CRITICAL
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002867static int ssl_remember_peer_pubkey(mbedtls_ssl_context *ssl,
2868 unsigned char *start, size_t len)
Hanno Becker6b8fbab2019-02-08 14:59:05 +00002869{
2870 unsigned char *end = start + len;
Janos Follath865b3eb2019-12-16 11:46:15 +00002871 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Hanno Becker6b8fbab2019-02-08 14:59:05 +00002872
2873 /* Make a copy of the peer's raw public key. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002874 mbedtls_pk_init(&ssl->handshake->peer_pubkey);
2875 ret = mbedtls_pk_parse_subpubkey(&start, end,
2876 &ssl->handshake->peer_pubkey);
2877 if (ret != 0) {
Hanno Becker6b8fbab2019-02-08 14:59:05 +00002878 /* We should have parsed the public key before. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002879 return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
Hanno Becker6b8fbab2019-02-08 14:59:05 +00002880 }
2881
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002882 return 0;
Hanno Becker6b8fbab2019-02-08 14:59:05 +00002883}
2884#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
2885
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002886int mbedtls_ssl_parse_certificate(mbedtls_ssl_context *ssl)
Hanno Becker68636192019-02-05 14:36:34 +00002887{
2888 int ret = 0;
Hanno Becker28f2fcd2019-02-07 10:11:07 +00002889 int crt_expected;
Manuel Pégourié-Gonnardfed37ed2017-08-15 13:27:41 +02002890#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
2891 const int authmode = ssl->handshake->sni_authmode != MBEDTLS_SSL_VERIFY_UNSET
2892 ? ssl->handshake->sni_authmode
2893 : ssl->conf->authmode;
2894#else
Johan Pascal4f099262020-09-22 10:59:26 +02002895 const int authmode = ssl->conf->authmode;
Manuel Pégourié-Gonnardfed37ed2017-08-15 13:27:41 +02002896#endif
Manuel Pégourié-Gonnard3bf49c42017-08-15 13:47:06 +02002897 void *rs_ctx = NULL;
Hanno Becker3dad3112019-02-05 17:19:52 +00002898 mbedtls_x509_crt *chain = NULL;
Manuel Pégourié-Gonnardfed37ed2017-08-15 13:27:41 +02002899
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002900 MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse certificate"));
Manuel Pégourié-Gonnardfed37ed2017-08-15 13:27:41 +02002901
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002902 crt_expected = ssl_parse_certificate_coordinate(ssl, authmode);
2903 if (crt_expected == SSL_CERTIFICATE_SKIP) {
2904 MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip parse certificate"));
Hanno Becker6bdfab22019-02-05 13:11:17 +00002905 goto exit;
Manuel Pégourié-Gonnardfed37ed2017-08-15 13:27:41 +02002906 }
2907
Gilles Peskineeccd8882020-03-10 12:19:08 +01002908#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002909 if (ssl->handshake->ecrs_enabled &&
2910 ssl->handshake->ecrs_state == ssl_ecrs_crt_verify) {
Hanno Becker3dad3112019-02-05 17:19:52 +00002911 chain = ssl->handshake->ecrs_peer_cert;
2912 ssl->handshake->ecrs_peer_cert = NULL;
Manuel Pégourié-Gonnard3bf49c42017-08-15 13:47:06 +02002913 goto crt_verify;
2914 }
2915#endif
2916
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002917 if ((ret = mbedtls_ssl_read_record(ssl, 1)) != 0) {
Manuel Pégourié-Gonnardfed37ed2017-08-15 13:27:41 +02002918 /* mbedtls_ssl_read_record may have sent an alert already. We
2919 let it decide whether to alert. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002920 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_read_record", ret);
Hanno Becker3dad3112019-02-05 17:19:52 +00002921 goto exit;
Manuel Pégourié-Gonnardfed37ed2017-08-15 13:27:41 +02002922 }
2923
Hanno Becker4a55f632019-02-05 12:49:06 +00002924#if defined(MBEDTLS_SSL_SRV_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002925 if (ssl_srv_check_client_no_crt_notification(ssl) == 0) {
Hanno Becker4a55f632019-02-05 12:49:06 +00002926 ssl->session_negotiate->verify_result = MBEDTLS_X509_BADCERT_MISSING;
Hanno Becker4a55f632019-02-05 12:49:06 +00002927
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002928 if (authmode != MBEDTLS_SSL_VERIFY_OPTIONAL) {
Hanno Becker6bdfab22019-02-05 13:11:17 +00002929 ret = MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002930 }
Hanno Becker4a55f632019-02-05 12:49:06 +00002931
Hanno Becker6bdfab22019-02-05 13:11:17 +00002932 goto exit;
Hanno Becker4a55f632019-02-05 12:49:06 +00002933 }
2934#endif /* MBEDTLS_SSL_SRV_C */
2935
Hanno Beckerc7bd7802019-02-05 15:37:23 +00002936 /* Clear existing peer CRT structure in case we tried to
2937 * reuse a session but it failed, and allocate a new one. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002938 ssl_clear_peer_cert(ssl->session_negotiate);
Hanno Becker3dad3112019-02-05 17:19:52 +00002939
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002940 chain = mbedtls_calloc(1, sizeof(mbedtls_x509_crt));
2941 if (chain == NULL) {
2942 MBEDTLS_SSL_DEBUG_MSG(1, ("alloc(%" MBEDTLS_PRINTF_SIZET " bytes) failed",
2943 sizeof(mbedtls_x509_crt)));
2944 mbedtls_ssl_send_alert_message(ssl,
2945 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
2946 MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR);
Hanno Becker7a955a02019-02-05 13:08:01 +00002947
Hanno Becker3dad3112019-02-05 17:19:52 +00002948 ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
2949 goto exit;
2950 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002951 mbedtls_x509_crt_init(chain);
Hanno Becker3dad3112019-02-05 17:19:52 +00002952
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002953 ret = ssl_parse_certificate_chain(ssl, chain);
2954 if (ret != 0) {
Hanno Becker3dad3112019-02-05 17:19:52 +00002955 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002956 }
Manuel Pégourié-Gonnardfed37ed2017-08-15 13:27:41 +02002957
Gilles Peskineeccd8882020-03-10 12:19:08 +01002958#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002959 if (ssl->handshake->ecrs_enabled) {
Manuel Pégourié-Gonnard0b23f162017-08-24 12:08:33 +02002960 ssl->handshake->ecrs_state = ssl_ecrs_crt_verify;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002961 }
Manuel Pégourié-Gonnard3bf49c42017-08-15 13:47:06 +02002962
2963crt_verify:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002964 if (ssl->handshake->ecrs_enabled) {
Manuel Pégourié-Gonnard3bf49c42017-08-15 13:47:06 +02002965 rs_ctx = &ssl->handshake->ecrs_ctx;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002966 }
Manuel Pégourié-Gonnard3bf49c42017-08-15 13:47:06 +02002967#endif
2968
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002969 ret = ssl_parse_certificate_verify(ssl, authmode,
2970 chain, rs_ctx);
2971 if (ret != 0) {
Hanno Becker3dad3112019-02-05 17:19:52 +00002972 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002973 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002974
Hanno Becker6bbd94c2019-02-05 17:02:28 +00002975#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
Hanno Becker6bbd94c2019-02-05 17:02:28 +00002976 {
Hanno Becker6b8fbab2019-02-08 14:59:05 +00002977 unsigned char *crt_start, *pk_start;
2978 size_t crt_len, pk_len;
Hanno Becker3dad3112019-02-05 17:19:52 +00002979
Hanno Becker6b8fbab2019-02-08 14:59:05 +00002980 /* We parse the CRT chain without copying, so
2981 * these pointers point into the input buffer,
2982 * and are hence still valid after freeing the
2983 * CRT chain. */
Hanno Becker6bbd94c2019-02-05 17:02:28 +00002984
Hanno Becker6b8fbab2019-02-08 14:59:05 +00002985 crt_start = chain->raw.p;
2986 crt_len = chain->raw.len;
Hanno Becker6bbd94c2019-02-05 17:02:28 +00002987
Hanno Becker6b8fbab2019-02-08 14:59:05 +00002988 pk_start = chain->pk_raw.p;
2989 pk_len = chain->pk_raw.len;
2990
2991 /* Free the CRT structures before computing
2992 * digest and copying the peer's public key. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002993 mbedtls_x509_crt_free(chain);
2994 mbedtls_free(chain);
Hanno Becker6b8fbab2019-02-08 14:59:05 +00002995 chain = NULL;
2996
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002997 ret = ssl_remember_peer_crt_digest(ssl, crt_start, crt_len);
2998 if (ret != 0) {
Hanno Beckera2747532019-02-06 16:19:04 +00002999 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003000 }
Hanno Becker6b8fbab2019-02-08 14:59:05 +00003001
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003002 ret = ssl_remember_peer_pubkey(ssl, pk_start, pk_len);
3003 if (ret != 0) {
Hanno Becker6b8fbab2019-02-08 14:59:05 +00003004 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003005 }
Hanno Beckera2747532019-02-06 16:19:04 +00003006 }
Hanno Becker6b8fbab2019-02-08 14:59:05 +00003007#else /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
3008 /* Pass ownership to session structure. */
Hanno Becker3dad3112019-02-05 17:19:52 +00003009 ssl->session_negotiate->peer_cert = chain;
3010 chain = NULL;
Hanno Becker6b8fbab2019-02-08 14:59:05 +00003011#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
Hanno Becker3dad3112019-02-05 17:19:52 +00003012
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003013 MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse certificate"));
Paul Bakker5121ce52009-01-03 21:22:43 +00003014
Hanno Becker6bdfab22019-02-05 13:11:17 +00003015exit:
3016
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003017 if (ret == 0) {
Hanno Becker3dad3112019-02-05 17:19:52 +00003018 ssl->state++;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003019 }
Hanno Becker3dad3112019-02-05 17:19:52 +00003020
Gilles Peskineeccd8882020-03-10 12:19:08 +01003021#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003022 if (ret == MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS) {
Hanno Becker3dad3112019-02-05 17:19:52 +00003023 ssl->handshake->ecrs_peer_cert = chain;
3024 chain = NULL;
3025 }
3026#endif
3027
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003028 if (chain != NULL) {
3029 mbedtls_x509_crt_free(chain);
3030 mbedtls_free(chain);
Hanno Becker3dad3112019-02-05 17:19:52 +00003031 }
3032
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003033 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00003034}
Gilles Peskineeccd8882020-03-10 12:19:08 +01003035#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
Paul Bakker5121ce52009-01-03 21:22:43 +00003036
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003037void mbedtls_ssl_optimize_checksum(mbedtls_ssl_context *ssl,
3038 const mbedtls_ssl_ciphersuite_t *ciphersuite_info)
Paul Bakker380da532012-04-18 16:10:25 +00003039{
Paul Bakkerfb08fd22013-08-27 15:06:26 +02003040 ((void) ciphersuite_info);
Paul Bakker769075d2012-11-24 11:26:46 +01003041
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003042#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
3043 defined(MBEDTLS_SSL_PROTO_TLS1_1)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003044 if (ssl->minor_ver < MBEDTLS_SSL_MINOR_VERSION_3) {
Paul Bakker48916f92012-09-16 19:57:18 +00003045 ssl->handshake->update_checksum = ssl_update_checksum_md5sha1;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003046 } else
Paul Bakkerd2f068e2013-08-27 21:19:20 +02003047#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003048#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
Gilles Peskined2d59372021-05-12 22:43:27 +02003049#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003050 if (ciphersuite_info->mac == MBEDTLS_MD_SHA384) {
Paul Bakkerd2f068e2013-08-27 21:19:20 +02003051 ssl->handshake->update_checksum = ssl_update_checksum_sha384;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003052 } else
Paul Bakkerd2f068e2013-08-27 21:19:20 +02003053#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003054#if defined(MBEDTLS_SHA256_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003055 if (ciphersuite_info->mac != MBEDTLS_MD_SHA384) {
Paul Bakker48916f92012-09-16 19:57:18 +00003056 ssl->handshake->update_checksum = ssl_update_checksum_sha256;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003057 } else
Paul Bakkerd2f068e2013-08-27 21:19:20 +02003058#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003059#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
Manuel Pégourié-Gonnard61edffe2014-04-11 17:07:31 +02003060 {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003061 MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
Paul Bakkerd2f068e2013-08-27 21:19:20 +02003062 return;
Manuel Pégourié-Gonnard61edffe2014-04-11 17:07:31 +02003063 }
Paul Bakker380da532012-04-18 16:10:25 +00003064}
Paul Bakkerf7abd422013-04-16 13:15:56 +02003065
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003066void mbedtls_ssl_reset_checksum(mbedtls_ssl_context *ssl)
Manuel Pégourié-Gonnard67427c02014-07-11 13:45:34 +02003067{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003068#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
3069 defined(MBEDTLS_SSL_PROTO_TLS1_1)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003070 mbedtls_md5_starts_ret(&ssl->handshake->fin_md5);
3071 mbedtls_sha1_starts_ret(&ssl->handshake->fin_sha1);
Manuel Pégourié-Gonnard67427c02014-07-11 13:45:34 +02003072#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003073#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
3074#if defined(MBEDTLS_SHA256_C)
Andrzej Kurekeb342242019-01-29 09:14:33 -05003075#if defined(MBEDTLS_USE_PSA_CRYPTO)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003076 psa_hash_abort(&ssl->handshake->fin_sha256_psa);
3077 psa_hash_setup(&ssl->handshake->fin_sha256_psa, PSA_ALG_SHA_256);
Andrzej Kurekeb342242019-01-29 09:14:33 -05003078#else
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003079 mbedtls_sha256_starts_ret(&ssl->handshake->fin_sha256, 0);
Manuel Pégourié-Gonnard67427c02014-07-11 13:45:34 +02003080#endif
Andrzej Kurekeb342242019-01-29 09:14:33 -05003081#endif
Gilles Peskined2d59372021-05-12 22:43:27 +02003082#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384)
Andrzej Kurekeb342242019-01-29 09:14:33 -05003083#if defined(MBEDTLS_USE_PSA_CRYPTO)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003084 psa_hash_abort(&ssl->handshake->fin_sha384_psa);
3085 psa_hash_setup(&ssl->handshake->fin_sha384_psa, PSA_ALG_SHA_384);
Andrzej Kurekeb342242019-01-29 09:14:33 -05003086#else
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003087 mbedtls_sha512_starts_ret(&ssl->handshake->fin_sha512, 1);
Manuel Pégourié-Gonnard67427c02014-07-11 13:45:34 +02003088#endif
Andrzej Kurekeb342242019-01-29 09:14:33 -05003089#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003090#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
Manuel Pégourié-Gonnard67427c02014-07-11 13:45:34 +02003091}
3092
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003093static void ssl_update_checksum_start(mbedtls_ssl_context *ssl,
3094 const unsigned char *buf, size_t len)
Paul Bakker380da532012-04-18 16:10:25 +00003095{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003096#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
3097 defined(MBEDTLS_SSL_PROTO_TLS1_1)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003098 mbedtls_md5_update_ret(&ssl->handshake->fin_md5, buf, len);
3099 mbedtls_sha1_update_ret(&ssl->handshake->fin_sha1, buf, len);
Paul Bakkerd2f068e2013-08-27 21:19:20 +02003100#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003101#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
3102#if defined(MBEDTLS_SHA256_C)
Andrzej Kurekeb342242019-01-29 09:14:33 -05003103#if defined(MBEDTLS_USE_PSA_CRYPTO)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003104 psa_hash_update(&ssl->handshake->fin_sha256_psa, buf, len);
Andrzej Kurekeb342242019-01-29 09:14:33 -05003105#else
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003106 mbedtls_sha256_update_ret(&ssl->handshake->fin_sha256, buf, len);
Paul Bakkerd2f068e2013-08-27 21:19:20 +02003107#endif
Andrzej Kurekeb342242019-01-29 09:14:33 -05003108#endif
Gilles Peskined2d59372021-05-12 22:43:27 +02003109#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384)
Andrzej Kurekeb342242019-01-29 09:14:33 -05003110#if defined(MBEDTLS_USE_PSA_CRYPTO)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003111 psa_hash_update(&ssl->handshake->fin_sha384_psa, buf, len);
Andrzej Kurekeb342242019-01-29 09:14:33 -05003112#else
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003113 mbedtls_sha512_update_ret(&ssl->handshake->fin_sha512, buf, len);
Paul Bakker769075d2012-11-24 11:26:46 +01003114#endif
Andrzej Kurekeb342242019-01-29 09:14:33 -05003115#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003116#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
Paul Bakker380da532012-04-18 16:10:25 +00003117}
3118
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003119#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
3120 defined(MBEDTLS_SSL_PROTO_TLS1_1)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003121static void ssl_update_checksum_md5sha1(mbedtls_ssl_context *ssl,
3122 const unsigned char *buf, size_t len)
Paul Bakker380da532012-04-18 16:10:25 +00003123{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003124 mbedtls_md5_update_ret(&ssl->handshake->fin_md5, buf, len);
3125 mbedtls_sha1_update_ret(&ssl->handshake->fin_sha1, buf, len);
Paul Bakker380da532012-04-18 16:10:25 +00003126}
Paul Bakkerd2f068e2013-08-27 21:19:20 +02003127#endif
Paul Bakker380da532012-04-18 16:10:25 +00003128
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003129#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
3130#if defined(MBEDTLS_SHA256_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003131static void ssl_update_checksum_sha256(mbedtls_ssl_context *ssl,
3132 const unsigned char *buf, size_t len)
Paul Bakker380da532012-04-18 16:10:25 +00003133{
Andrzej Kurekeb342242019-01-29 09:14:33 -05003134#if defined(MBEDTLS_USE_PSA_CRYPTO)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003135 psa_hash_update(&ssl->handshake->fin_sha256_psa, buf, len);
Andrzej Kurekeb342242019-01-29 09:14:33 -05003136#else
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003137 mbedtls_sha256_update_ret(&ssl->handshake->fin_sha256, buf, len);
Andrzej Kurekeb342242019-01-29 09:14:33 -05003138#endif
Paul Bakker380da532012-04-18 16:10:25 +00003139}
Paul Bakkerd2f068e2013-08-27 21:19:20 +02003140#endif
Paul Bakker380da532012-04-18 16:10:25 +00003141
Gilles Peskined2d59372021-05-12 22:43:27 +02003142#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003143static void ssl_update_checksum_sha384(mbedtls_ssl_context *ssl,
3144 const unsigned char *buf, size_t len)
Paul Bakker380da532012-04-18 16:10:25 +00003145{
Andrzej Kurekeb342242019-01-29 09:14:33 -05003146#if defined(MBEDTLS_USE_PSA_CRYPTO)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003147 psa_hash_update(&ssl->handshake->fin_sha384_psa, buf, len);
Andrzej Kurekeb342242019-01-29 09:14:33 -05003148#else
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003149 mbedtls_sha512_update_ret(&ssl->handshake->fin_sha512, buf, len);
Andrzej Kurekeb342242019-01-29 09:14:33 -05003150#endif
Paul Bakker380da532012-04-18 16:10:25 +00003151}
Paul Bakker769075d2012-11-24 11:26:46 +01003152#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003153#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
Paul Bakker380da532012-04-18 16:10:25 +00003154
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003155#if defined(MBEDTLS_SSL_PROTO_SSL3)
David Horstmann68014b22025-03-10 14:10:11 +00003156static int ssl_calc_finished_ssl(
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003157 mbedtls_ssl_context *ssl, unsigned char *buf, int from)
Paul Bakker5121ce52009-01-03 21:22:43 +00003158{
Paul Bakker3c2122f2013-06-24 19:03:14 +02003159 const char *sender;
Manuel Pégourié-Gonnardc0bf01e2015-07-06 16:11:18 +02003160 mbedtls_md5_context md5;
3161 mbedtls_sha1_context sha1;
Paul Bakker1ef83d62012-04-11 12:09:53 +00003162
Paul Bakker5121ce52009-01-03 21:22:43 +00003163 unsigned char padbuf[48];
3164 unsigned char md5sum[16];
3165 unsigned char sha1sum[20];
3166
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003167 mbedtls_ssl_session *session = ssl->session_negotiate;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003168 if (!session) {
Paul Bakker48916f92012-09-16 19:57:18 +00003169 session = ssl->session;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003170 }
Paul Bakker48916f92012-09-16 19:57:18 +00003171
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003172 MBEDTLS_SSL_DEBUG_MSG(2, ("=> calc finished ssl"));
Paul Bakker1ef83d62012-04-11 12:09:53 +00003173
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003174 mbedtls_md5_init(&md5);
3175 mbedtls_sha1_init(&sha1);
Manuel Pégourié-Gonnard001f2b62015-07-06 16:21:13 +02003176
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003177 mbedtls_md5_clone(&md5, &ssl->handshake->fin_md5);
3178 mbedtls_sha1_clone(&sha1, &ssl->handshake->fin_sha1);
Paul Bakker5121ce52009-01-03 21:22:43 +00003179
3180 /*
3181 * SSLv3:
3182 * hash =
3183 * MD5( master + pad2 +
3184 * MD5( handshake + sender + master + pad1 ) )
3185 * + SHA1( master + pad2 +
3186 * SHA1( handshake + sender + master + pad1 ) )
Paul Bakker5121ce52009-01-03 21:22:43 +00003187 */
3188
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003189#if !defined(MBEDTLS_MD5_ALT)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003190 MBEDTLS_SSL_DEBUG_BUF(4, "finished md5 state", (unsigned char *)
3191 md5.state, sizeof(md5.state));
Paul Bakker90995b52013-06-24 19:20:35 +02003192#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003193
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003194#if !defined(MBEDTLS_SHA1_ALT)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003195 MBEDTLS_SSL_DEBUG_BUF(4, "finished sha1 state", (unsigned char *)
3196 sha1.state, sizeof(sha1.state));
Paul Bakker90995b52013-06-24 19:20:35 +02003197#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003198
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003199 sender = (from == MBEDTLS_SSL_IS_CLIENT) ? "CLNT"
Paul Bakker3c2122f2013-06-24 19:03:14 +02003200 : "SRVR";
Paul Bakker5121ce52009-01-03 21:22:43 +00003201
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003202 memset(padbuf, 0x36, 48);
Paul Bakker5121ce52009-01-03 21:22:43 +00003203
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003204 mbedtls_md5_update_ret(&md5, (const unsigned char *) sender, 4);
3205 mbedtls_md5_update_ret(&md5, session->master, 48);
3206 mbedtls_md5_update_ret(&md5, padbuf, 48);
3207 mbedtls_md5_finish_ret(&md5, md5sum);
Paul Bakker5121ce52009-01-03 21:22:43 +00003208
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003209 mbedtls_sha1_update_ret(&sha1, (const unsigned char *) sender, 4);
3210 mbedtls_sha1_update_ret(&sha1, session->master, 48);
3211 mbedtls_sha1_update_ret(&sha1, padbuf, 40);
3212 mbedtls_sha1_finish_ret(&sha1, sha1sum);
Paul Bakker5121ce52009-01-03 21:22:43 +00003213
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003214 memset(padbuf, 0x5C, 48);
Paul Bakker5121ce52009-01-03 21:22:43 +00003215
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003216 mbedtls_md5_starts_ret(&md5);
3217 mbedtls_md5_update_ret(&md5, session->master, 48);
3218 mbedtls_md5_update_ret(&md5, padbuf, 48);
3219 mbedtls_md5_update_ret(&md5, md5sum, 16);
3220 mbedtls_md5_finish_ret(&md5, buf);
Paul Bakker5121ce52009-01-03 21:22:43 +00003221
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003222 mbedtls_sha1_starts_ret(&sha1);
3223 mbedtls_sha1_update_ret(&sha1, session->master, 48);
3224 mbedtls_sha1_update_ret(&sha1, padbuf, 40);
3225 mbedtls_sha1_update_ret(&sha1, sha1sum, 20);
3226 mbedtls_sha1_finish_ret(&sha1, buf + 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00003227
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003228 MBEDTLS_SSL_DEBUG_BUF(3, "calc finished result", buf, 36);
Paul Bakker5121ce52009-01-03 21:22:43 +00003229
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003230 mbedtls_md5_free(&md5);
3231 mbedtls_sha1_free(&sha1);
Paul Bakker5121ce52009-01-03 21:22:43 +00003232
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003233 mbedtls_platform_zeroize(padbuf, sizeof(padbuf));
3234 mbedtls_platform_zeroize(md5sum, sizeof(md5sum));
3235 mbedtls_platform_zeroize(sha1sum, sizeof(sha1sum));
Paul Bakker5121ce52009-01-03 21:22:43 +00003236
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003237 MBEDTLS_SSL_DEBUG_MSG(2, ("<= calc finished"));
David Horstmann68014b22025-03-10 14:10:11 +00003238
3239 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +00003240}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003241#endif /* MBEDTLS_SSL_PROTO_SSL3 */
Paul Bakker5121ce52009-01-03 21:22:43 +00003242
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003243#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1)
David Horstmann68014b22025-03-10 14:10:11 +00003244static int ssl_calc_finished_tls(
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003245 mbedtls_ssl_context *ssl, unsigned char *buf, int from)
Paul Bakker5121ce52009-01-03 21:22:43 +00003246{
Paul Bakker1ef83d62012-04-11 12:09:53 +00003247 int len = 12;
Paul Bakker3c2122f2013-06-24 19:03:14 +02003248 const char *sender;
Manuel Pégourié-Gonnardc0bf01e2015-07-06 16:11:18 +02003249 mbedtls_md5_context md5;
3250 mbedtls_sha1_context sha1;
Paul Bakker1ef83d62012-04-11 12:09:53 +00003251 unsigned char padbuf[36];
Paul Bakker5121ce52009-01-03 21:22:43 +00003252
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003253 mbedtls_ssl_session *session = ssl->session_negotiate;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003254 if (!session) {
Paul Bakker48916f92012-09-16 19:57:18 +00003255 session = ssl->session;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003256 }
Paul Bakker48916f92012-09-16 19:57:18 +00003257
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003258 MBEDTLS_SSL_DEBUG_MSG(2, ("=> calc finished tls"));
Paul Bakker5121ce52009-01-03 21:22:43 +00003259
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003260 mbedtls_md5_init(&md5);
3261 mbedtls_sha1_init(&sha1);
Manuel Pégourié-Gonnard001f2b62015-07-06 16:21:13 +02003262
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003263 mbedtls_md5_clone(&md5, &ssl->handshake->fin_md5);
3264 mbedtls_sha1_clone(&sha1, &ssl->handshake->fin_sha1);
Paul Bakker5121ce52009-01-03 21:22:43 +00003265
Paul Bakker1ef83d62012-04-11 12:09:53 +00003266 /*
3267 * TLSv1:
3268 * hash = PRF( master, finished_label,
3269 * MD5( handshake ) + SHA1( handshake ) )[0..11]
3270 */
Paul Bakker5121ce52009-01-03 21:22:43 +00003271
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003272#if !defined(MBEDTLS_MD5_ALT)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003273 MBEDTLS_SSL_DEBUG_BUF(4, "finished md5 state", (unsigned char *)
3274 md5.state, sizeof(md5.state));
Paul Bakker90995b52013-06-24 19:20:35 +02003275#endif
Paul Bakker1ef83d62012-04-11 12:09:53 +00003276
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003277#if !defined(MBEDTLS_SHA1_ALT)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003278 MBEDTLS_SSL_DEBUG_BUF(4, "finished sha1 state", (unsigned char *)
3279 sha1.state, sizeof(sha1.state));
Paul Bakker90995b52013-06-24 19:20:35 +02003280#endif
Paul Bakker1ef83d62012-04-11 12:09:53 +00003281
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003282 sender = (from == MBEDTLS_SSL_IS_CLIENT)
Paul Bakker3c2122f2013-06-24 19:03:14 +02003283 ? "client finished"
3284 : "server finished";
Paul Bakker1ef83d62012-04-11 12:09:53 +00003285
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003286 mbedtls_md5_finish_ret(&md5, padbuf);
3287 mbedtls_sha1_finish_ret(&sha1, padbuf + 16);
Paul Bakker1ef83d62012-04-11 12:09:53 +00003288
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003289 ssl->handshake->tls_prf(session->master, 48, sender,
3290 padbuf, 36, buf, len);
Paul Bakker1ef83d62012-04-11 12:09:53 +00003291
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003292 MBEDTLS_SSL_DEBUG_BUF(3, "calc finished result", buf, len);
Paul Bakker1ef83d62012-04-11 12:09:53 +00003293
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003294 mbedtls_md5_free(&md5);
3295 mbedtls_sha1_free(&sha1);
Paul Bakker1ef83d62012-04-11 12:09:53 +00003296
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003297 mbedtls_platform_zeroize(padbuf, sizeof(padbuf));
Paul Bakker1ef83d62012-04-11 12:09:53 +00003298
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003299 MBEDTLS_SSL_DEBUG_MSG(2, ("<= calc finished"));
David Horstmann68014b22025-03-10 14:10:11 +00003300
3301 return 0;
Paul Bakker1ef83d62012-04-11 12:09:53 +00003302}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003303#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 */
Paul Bakker1ef83d62012-04-11 12:09:53 +00003304
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003305#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
3306#if defined(MBEDTLS_SHA256_C)
David Horstmann68014b22025-03-10 14:10:11 +00003307static int ssl_calc_finished_tls_sha256(
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003308 mbedtls_ssl_context *ssl, unsigned char *buf, int from)
Paul Bakker1ef83d62012-04-11 12:09:53 +00003309{
3310 int len = 12;
Paul Bakker3c2122f2013-06-24 19:03:14 +02003311 const char *sender;
Paul Bakker1ef83d62012-04-11 12:09:53 +00003312 unsigned char padbuf[32];
Andrzej Kurekeb342242019-01-29 09:14:33 -05003313#if defined(MBEDTLS_USE_PSA_CRYPTO)
3314 size_t hash_size;
Jaeden Amero34973232019-02-20 10:32:28 +00003315 psa_hash_operation_t sha256_psa = PSA_HASH_OPERATION_INIT;
Andrzej Kurekeb342242019-01-29 09:14:33 -05003316 psa_status_t status;
3317#else
3318 mbedtls_sha256_context sha256;
3319#endif
Paul Bakker1ef83d62012-04-11 12:09:53 +00003320
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003321 mbedtls_ssl_session *session = ssl->session_negotiate;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003322 if (!session) {
Paul Bakker48916f92012-09-16 19:57:18 +00003323 session = ssl->session;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003324 }
Paul Bakker48916f92012-09-16 19:57:18 +00003325
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003326 sender = (from == MBEDTLS_SSL_IS_CLIENT)
Andrzej Kurekeb342242019-01-29 09:14:33 -05003327 ? "client finished"
3328 : "server finished";
3329
3330#if defined(MBEDTLS_USE_PSA_CRYPTO)
3331 sha256_psa = psa_hash_operation_init();
3332
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003333 MBEDTLS_SSL_DEBUG_MSG(2, ("=> calc PSA finished tls sha256"));
Andrzej Kurekeb342242019-01-29 09:14:33 -05003334
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003335 status = psa_hash_clone(&ssl->handshake->fin_sha256_psa, &sha256_psa);
3336 if (status != PSA_SUCCESS) {
3337 MBEDTLS_SSL_DEBUG_MSG(2, ("PSA hash clone failed"));
David Horstmann09072662025-03-12 12:03:13 +00003338 return mbedtls_ssl_md_error_from_psa(status);
Andrzej Kurekeb342242019-01-29 09:14:33 -05003339 }
3340
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003341 status = psa_hash_finish(&sha256_psa, padbuf, sizeof(padbuf), &hash_size);
3342 if (status != PSA_SUCCESS) {
3343 MBEDTLS_SSL_DEBUG_MSG(2, ("PSA hash finish failed"));
David Horstmann09072662025-03-12 12:03:13 +00003344 return mbedtls_ssl_md_error_from_psa(status);
Andrzej Kurekeb342242019-01-29 09:14:33 -05003345 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003346 MBEDTLS_SSL_DEBUG_BUF(3, "PSA calculated padbuf", padbuf, 32);
Andrzej Kurekeb342242019-01-29 09:14:33 -05003347#else
3348
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003349 mbedtls_sha256_init(&sha256);
Manuel Pégourié-Gonnard001f2b62015-07-06 16:21:13 +02003350
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003351 MBEDTLS_SSL_DEBUG_MSG(2, ("=> calc finished tls sha256"));
Paul Bakker1ef83d62012-04-11 12:09:53 +00003352
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003353 mbedtls_sha256_clone(&sha256, &ssl->handshake->fin_sha256);
Paul Bakker1ef83d62012-04-11 12:09:53 +00003354
3355 /*
3356 * TLSv1.2:
3357 * hash = PRF( master, finished_label,
3358 * Hash( handshake ) )[0.11]
3359 */
3360
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003361#if !defined(MBEDTLS_SHA256_ALT)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003362 MBEDTLS_SSL_DEBUG_BUF(4, "finished sha2 state", (unsigned char *)
3363 sha256.state, sizeof(sha256.state));
Paul Bakker90995b52013-06-24 19:20:35 +02003364#endif
Paul Bakker1ef83d62012-04-11 12:09:53 +00003365
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003366 mbedtls_sha256_finish_ret(&sha256, padbuf);
3367 mbedtls_sha256_free(&sha256);
Andrzej Kurekeb342242019-01-29 09:14:33 -05003368#endif /* MBEDTLS_USE_PSA_CRYPTO */
Paul Bakker1ef83d62012-04-11 12:09:53 +00003369
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003370 ssl->handshake->tls_prf(session->master, 48, sender,
3371 padbuf, 32, buf, len);
Paul Bakker1ef83d62012-04-11 12:09:53 +00003372
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003373 MBEDTLS_SSL_DEBUG_BUF(3, "calc finished result", buf, len);
Paul Bakker1ef83d62012-04-11 12:09:53 +00003374
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003375 mbedtls_platform_zeroize(padbuf, sizeof(padbuf));
Paul Bakker1ef83d62012-04-11 12:09:53 +00003376
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003377 MBEDTLS_SSL_DEBUG_MSG(2, ("<= calc finished"));
David Horstmann68014b22025-03-10 14:10:11 +00003378
3379 return 0;
Paul Bakker1ef83d62012-04-11 12:09:53 +00003380}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003381#endif /* MBEDTLS_SHA256_C */
Paul Bakker1ef83d62012-04-11 12:09:53 +00003382
Gilles Peskined2d59372021-05-12 22:43:27 +02003383#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384)
Rodrigo Dias Corread596ca82020-11-25 00:42:28 -03003384
David Horstmann68014b22025-03-10 14:10:11 +00003385static int ssl_calc_finished_tls_sha384(
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003386 mbedtls_ssl_context *ssl, unsigned char *buf, int from)
Paul Bakkerca4ab492012-04-18 14:23:57 +00003387{
3388 int len = 12;
Paul Bakker3c2122f2013-06-24 19:03:14 +02003389 const char *sender;
Rodrigo Dias Corread596ca82020-11-25 00:42:28 -03003390 unsigned char padbuf[48];
Andrzej Kurekeb342242019-01-29 09:14:33 -05003391#if defined(MBEDTLS_USE_PSA_CRYPTO)
3392 size_t hash_size;
Jaeden Amero34973232019-02-20 10:32:28 +00003393 psa_hash_operation_t sha384_psa = PSA_HASH_OPERATION_INIT;
Andrzej Kurekeb342242019-01-29 09:14:33 -05003394 psa_status_t status;
3395#else
3396 mbedtls_sha512_context sha512;
3397#endif
Paul Bakkerca4ab492012-04-18 14:23:57 +00003398
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003399 mbedtls_ssl_session *session = ssl->session_negotiate;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003400 if (!session) {
Paul Bakker48916f92012-09-16 19:57:18 +00003401 session = ssl->session;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003402 }
Paul Bakker48916f92012-09-16 19:57:18 +00003403
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003404 sender = (from == MBEDTLS_SSL_IS_CLIENT)
Andrzej Kurekeb342242019-01-29 09:14:33 -05003405 ? "client finished"
3406 : "server finished";
3407
3408#if defined(MBEDTLS_USE_PSA_CRYPTO)
Andrzej Kurek972fba52019-01-30 03:29:12 -05003409 sha384_psa = psa_hash_operation_init();
Andrzej Kurekeb342242019-01-29 09:14:33 -05003410
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003411 MBEDTLS_SSL_DEBUG_MSG(2, ("=> calc PSA finished tls sha384"));
Andrzej Kurekeb342242019-01-29 09:14:33 -05003412
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003413 status = psa_hash_clone(&ssl->handshake->fin_sha384_psa, &sha384_psa);
3414 if (status != PSA_SUCCESS) {
3415 MBEDTLS_SSL_DEBUG_MSG(2, ("PSA hash clone failed"));
David Horstmann09072662025-03-12 12:03:13 +00003416 return mbedtls_ssl_md_error_from_psa(status);
Andrzej Kurekeb342242019-01-29 09:14:33 -05003417 }
3418
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003419 status = psa_hash_finish(&sha384_psa, padbuf, sizeof(padbuf), &hash_size);
3420 if (status != PSA_SUCCESS) {
3421 MBEDTLS_SSL_DEBUG_MSG(2, ("PSA hash finish failed"));
David Horstmann09072662025-03-12 12:03:13 +00003422 return mbedtls_ssl_md_error_from_psa(status);
Andrzej Kurekeb342242019-01-29 09:14:33 -05003423 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003424 MBEDTLS_SSL_DEBUG_BUF(3, "PSA calculated padbuf", padbuf, 48);
Andrzej Kurekeb342242019-01-29 09:14:33 -05003425#else
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003426 mbedtls_sha512_init(&sha512);
Manuel Pégourié-Gonnard001f2b62015-07-06 16:21:13 +02003427
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003428 MBEDTLS_SSL_DEBUG_MSG(2, ("=> calc finished tls sha384"));
Paul Bakkerca4ab492012-04-18 14:23:57 +00003429
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003430 mbedtls_sha512_clone(&sha512, &ssl->handshake->fin_sha512);
Paul Bakkerca4ab492012-04-18 14:23:57 +00003431
3432 /*
3433 * TLSv1.2:
3434 * hash = PRF( master, finished_label,
3435 * Hash( handshake ) )[0.11]
3436 */
3437
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003438#if !defined(MBEDTLS_SHA512_ALT)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003439 MBEDTLS_SSL_DEBUG_BUF(4, "finished sha512 state", (unsigned char *)
3440 sha512.state, sizeof(sha512.state));
Paul Bakker90995b52013-06-24 19:20:35 +02003441#endif
Gilles Peskinebb66dac2021-05-13 00:00:45 +02003442 /* mbedtls_sha512_finish_ret's output parameter is declared as a
Tom Cosgrove49f99bc2022-12-04 16:44:21 +00003443 * 64-byte buffer, but since we're using SHA-384, we know that the
Gilles Peskinebb66dac2021-05-13 00:00:45 +02003444 * output fits in 48 bytes. This is correct C, but GCC 11.1 warns
3445 * about it.
Rodrigo Dias Corread596ca82020-11-25 00:42:28 -03003446 */
Gilles Peskinebb66dac2021-05-13 00:00:45 +02003447#if defined(__GNUC__) && __GNUC__ >= 11
3448#pragma GCC diagnostic push
3449#pragma GCC diagnostic ignored "-Wstringop-overflow"
3450#endif
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003451 mbedtls_sha512_finish_ret(&sha512, padbuf);
Gilles Peskinebb66dac2021-05-13 00:00:45 +02003452#if defined(__GNUC__) && __GNUC__ >= 11
3453#pragma GCC diagnostic pop
3454#endif
Paul Bakkerca4ab492012-04-18 14:23:57 +00003455
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003456 mbedtls_sha512_free(&sha512);
Andrzej Kurekeb342242019-01-29 09:14:33 -05003457#endif
Paul Bakkerca4ab492012-04-18 14:23:57 +00003458
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003459 ssl->handshake->tls_prf(session->master, 48, sender,
3460 padbuf, 48, buf, len);
Paul Bakkerca4ab492012-04-18 14:23:57 +00003461
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003462 MBEDTLS_SSL_DEBUG_BUF(3, "calc finished result", buf, len);
Paul Bakkerca4ab492012-04-18 14:23:57 +00003463
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003464 mbedtls_platform_zeroize(padbuf, sizeof(padbuf));
Paul Bakkerca4ab492012-04-18 14:23:57 +00003465
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003466 MBEDTLS_SSL_DEBUG_MSG(2, ("<= calc finished"));
David Horstmann68014b22025-03-10 14:10:11 +00003467
3468 return 0;
Paul Bakkerca4ab492012-04-18 14:23:57 +00003469}
Gilles Peskined2d59372021-05-12 22:43:27 +02003470#endif /* MBEDTLS_SHA512_C && !MBEDTLS_SHA512_NO_SHA384 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003471#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
Paul Bakkerca4ab492012-04-18 14:23:57 +00003472
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003473void mbedtls_ssl_handshake_wrapup_free_hs_transform(mbedtls_ssl_context *ssl)
Paul Bakker48916f92012-09-16 19:57:18 +00003474{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003475 MBEDTLS_SSL_DEBUG_MSG(3, ("=> handshake wrapup: final free"));
Paul Bakker48916f92012-09-16 19:57:18 +00003476
3477 /*
3478 * Free our handshake params
3479 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003480 mbedtls_ssl_handshake_free(ssl);
3481 mbedtls_free(ssl->handshake);
Paul Bakker48916f92012-09-16 19:57:18 +00003482 ssl->handshake = NULL;
3483
3484 /*
Shaun Case0e7791f2021-12-20 21:14:10 -08003485 * Free the previous transform and switch in the current one
Paul Bakker48916f92012-09-16 19:57:18 +00003486 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003487 if (ssl->transform) {
3488 mbedtls_ssl_transform_free(ssl->transform);
3489 mbedtls_free(ssl->transform);
Paul Bakker48916f92012-09-16 19:57:18 +00003490 }
3491 ssl->transform = ssl->transform_negotiate;
3492 ssl->transform_negotiate = NULL;
3493
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003494 MBEDTLS_SSL_DEBUG_MSG(3, ("<= handshake wrapup: final free"));
Manuel Pégourié-Gonnardabf16242014-09-23 09:42:16 +02003495}
3496
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003497void mbedtls_ssl_handshake_wrapup(mbedtls_ssl_context *ssl)
Manuel Pégourié-Gonnardabf16242014-09-23 09:42:16 +02003498{
3499 int resume = ssl->handshake->resume;
3500
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003501 MBEDTLS_SSL_DEBUG_MSG(3, ("=> handshake wrapup"));
Manuel Pégourié-Gonnardabf16242014-09-23 09:42:16 +02003502
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003503#if defined(MBEDTLS_SSL_RENEGOTIATION)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003504 if (ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS) {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003505 ssl->renego_status = MBEDTLS_SSL_RENEGOTIATION_DONE;
Manuel Pégourié-Gonnardabf16242014-09-23 09:42:16 +02003506 ssl->renego_records_seen = 0;
3507 }
Manuel Pégourié-Gonnard615e6772014-11-03 08:23:14 +01003508#endif
Manuel Pégourié-Gonnardabf16242014-09-23 09:42:16 +02003509
3510 /*
3511 * Free the previous session and switch in the current one
3512 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003513 if (ssl->session) {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003514#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
Manuel Pégourié-Gonnard1a034732014-11-04 17:36:18 +01003515 /* RFC 7366 3.1: keep the EtM state */
3516 ssl->session_negotiate->encrypt_then_mac =
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003517 ssl->session->encrypt_then_mac;
Manuel Pégourié-Gonnard1a034732014-11-04 17:36:18 +01003518#endif
3519
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003520 mbedtls_ssl_session_free(ssl->session);
3521 mbedtls_free(ssl->session);
Paul Bakker0a597072012-09-25 21:55:46 +00003522 }
3523 ssl->session = ssl->session_negotiate;
Paul Bakker48916f92012-09-16 19:57:18 +00003524 ssl->session_negotiate = NULL;
3525
Paul Bakker0a597072012-09-25 21:55:46 +00003526 /*
3527 * Add cache entry
3528 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003529 if (ssl->conf->f_set_cache != NULL &&
Manuel Pégourié-Gonnard12ad7982015-06-18 15:50:37 +02003530 ssl->session->id_len != 0 &&
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003531 resume == 0) {
3532 if (ssl->conf->f_set_cache(ssl->conf->p_cache, ssl->session) != 0) {
3533 MBEDTLS_SSL_DEBUG_MSG(1, ("cache did not store session"));
3534 }
Manuel Pégourié-Gonnardc086cce2013-08-02 14:13:02 +02003535 }
Paul Bakker0a597072012-09-25 21:55:46 +00003536
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003537#if defined(MBEDTLS_SSL_PROTO_DTLS)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003538 if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
3539 ssl->handshake->flight != NULL) {
Manuel Pégourié-Gonnard6b651412014-10-01 18:29:03 +02003540 /* Cancel handshake timer */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003541 mbedtls_ssl_set_timer(ssl, 0);
Manuel Pégourié-Gonnard6b651412014-10-01 18:29:03 +02003542
Manuel Pégourié-Gonnardabf16242014-09-23 09:42:16 +02003543 /* Keep last flight around in case we need to resend it:
3544 * we need the handshake and transform structures for that */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003545 MBEDTLS_SSL_DEBUG_MSG(3, ("skip freeing handshake and transform"));
3546 } else
Manuel Pégourié-Gonnardabf16242014-09-23 09:42:16 +02003547#endif
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003548 mbedtls_ssl_handshake_wrapup_free_hs_transform(ssl);
Manuel Pégourié-Gonnardabf16242014-09-23 09:42:16 +02003549
Paul Bakker48916f92012-09-16 19:57:18 +00003550 ssl->state++;
3551
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003552 MBEDTLS_SSL_DEBUG_MSG(3, ("<= handshake wrapup"));
Paul Bakker48916f92012-09-16 19:57:18 +00003553}
3554
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003555int mbedtls_ssl_write_finished(mbedtls_ssl_context *ssl)
Paul Bakker1ef83d62012-04-11 12:09:53 +00003556{
Manuel Pégourié-Gonnard879a4f92014-07-11 22:31:12 +02003557 int ret, hash_len;
Paul Bakker1ef83d62012-04-11 12:09:53 +00003558
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003559 MBEDTLS_SSL_DEBUG_MSG(2, ("=> write finished"));
Paul Bakker1ef83d62012-04-11 12:09:53 +00003560
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003561 mbedtls_ssl_update_out_pointers(ssl, ssl->transform_negotiate);
Paul Bakker92be97b2013-01-02 17:30:03 +01003562
David Horstmann68014b22025-03-10 14:10:11 +00003563 ret = ssl->handshake->calc_finished(ssl, ssl->out_msg + 4,
3564 ssl->conf->endpoint);
3565 if (ret != 0) {
3566 MBEDTLS_SSL_DEBUG_RET(1, "calc_finished", ret);
3567 return ret;
3568 }
Paul Bakker1ef83d62012-04-11 12:09:53 +00003569
Manuel Pégourié-Gonnard214a8482016-02-22 11:27:26 +01003570 /*
3571 * RFC 5246 7.4.9 (Page 63) says 12 is the default length and ciphersuites
3572 * may define some other value. Currently (early 2016), no defined
3573 * ciphersuite does this (and this is unlikely to change as activity has
3574 * moved to TLS 1.3 now) so we can keep the hardcoded 12 here.
3575 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003576 hash_len = (ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0) ? 36 : 12;
Paul Bakker5121ce52009-01-03 21:22:43 +00003577
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003578#if defined(MBEDTLS_SSL_RENEGOTIATION)
Paul Bakker48916f92012-09-16 19:57:18 +00003579 ssl->verify_data_len = hash_len;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003580 memcpy(ssl->own_verify_data, ssl->out_msg + 4, hash_len);
Manuel Pégourié-Gonnard615e6772014-11-03 08:23:14 +01003581#endif
Paul Bakker48916f92012-09-16 19:57:18 +00003582
Paul Bakker5121ce52009-01-03 21:22:43 +00003583 ssl->out_msglen = 4 + hash_len;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003584 ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
3585 ssl->out_msg[0] = MBEDTLS_SSL_HS_FINISHED;
Paul Bakker5121ce52009-01-03 21:22:43 +00003586
3587 /*
3588 * In case of session resuming, invert the client and server
3589 * ChangeCipherSpec messages order.
3590 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003591 if (ssl->handshake->resume != 0) {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003592#if defined(MBEDTLS_SSL_CLI_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003593 if (ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT) {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003594 ssl->state = MBEDTLS_SSL_HANDSHAKE_WRAPUP;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003595 }
Manuel Pégourié-Gonnardd16d1cb2014-11-20 18:15:05 +01003596#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003597#if defined(MBEDTLS_SSL_SRV_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003598 if (ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER) {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003599 ssl->state = MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003600 }
Manuel Pégourié-Gonnardd16d1cb2014-11-20 18:15:05 +01003601#endif
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003602 } else {
Paul Bakker5121ce52009-01-03 21:22:43 +00003603 ssl->state++;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003604 }
Paul Bakker5121ce52009-01-03 21:22:43 +00003605
Paul Bakker48916f92012-09-16 19:57:18 +00003606 /*
Paul Bakkerb9e4e2c2014-05-01 14:18:25 +02003607 * Switch to our negotiated transform and session parameters for outbound
3608 * data.
Paul Bakker48916f92012-09-16 19:57:18 +00003609 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003610 MBEDTLS_SSL_DEBUG_MSG(3, ("switching to new transform spec for outbound data"));
Manuel Pégourié-Gonnard5afb1672014-02-16 18:33:22 +01003611
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003612#if defined(MBEDTLS_SSL_PROTO_DTLS)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003613 if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
Manuel Pégourié-Gonnard879a4f92014-07-11 22:31:12 +02003614 unsigned char i;
3615
Manuel Pégourié-Gonnard5d8ba532014-09-19 15:09:21 +02003616 /* Remember current epoch settings for resending */
3617 ssl->handshake->alt_transform_out = ssl->transform_out;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003618 memcpy(ssl->handshake->alt_out_ctr, ssl->cur_out_ctr, 8);
Manuel Pégourié-Gonnard5d8ba532014-09-19 15:09:21 +02003619
Manuel Pégourié-Gonnard879a4f92014-07-11 22:31:12 +02003620 /* Set sequence_number to zero */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003621 memset(ssl->cur_out_ctr + 2, 0, 6);
Manuel Pégourié-Gonnard879a4f92014-07-11 22:31:12 +02003622
3623 /* Increment epoch */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003624 for (i = 2; i > 0; i--) {
3625 if (++ssl->cur_out_ctr[i - 1] != 0) {
Manuel Pégourié-Gonnard879a4f92014-07-11 22:31:12 +02003626 break;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003627 }
3628 }
Manuel Pégourié-Gonnard879a4f92014-07-11 22:31:12 +02003629
3630 /* The loop goes to its end iff the counter is wrapping */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003631 if (i == 0) {
3632 MBEDTLS_SSL_DEBUG_MSG(1, ("DTLS epoch would wrap"));
3633 return MBEDTLS_ERR_SSL_COUNTER_WRAPPING;
Manuel Pégourié-Gonnard879a4f92014-07-11 22:31:12 +02003634 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003635 } else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003636#endif /* MBEDTLS_SSL_PROTO_DTLS */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003637 memset(ssl->cur_out_ctr, 0, 8);
Paul Bakker5121ce52009-01-03 21:22:43 +00003638
Manuel Pégourié-Gonnard5d8ba532014-09-19 15:09:21 +02003639 ssl->transform_out = ssl->transform_negotiate;
3640 ssl->session_out = ssl->session_negotiate;
3641
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003642#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003643 if (mbedtls_ssl_hw_record_activate != NULL) {
3644 if ((ret = mbedtls_ssl_hw_record_activate(ssl, MBEDTLS_SSL_CHANNEL_OUTBOUND)) != 0) {
3645 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_hw_record_activate", ret);
3646 return MBEDTLS_ERR_SSL_HW_ACCEL_FAILED;
Paul Bakker07eb38b2012-12-19 14:42:06 +01003647 }
3648 }
3649#endif
3650
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003651#if defined(MBEDTLS_SSL_PROTO_DTLS)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003652 if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
3653 mbedtls_ssl_send_flight_completed(ssl);
3654 }
Manuel Pégourié-Gonnard7de3c9e2014-09-29 15:29:48 +02003655#endif
3656
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003657 if ((ret = mbedtls_ssl_write_handshake_msg(ssl)) != 0) {
3658 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_handshake_msg", ret);
3659 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00003660 }
3661
Manuel Pégourié-Gonnard87a346f2017-09-13 12:45:21 +02003662#if defined(MBEDTLS_SSL_PROTO_DTLS)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003663 if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
3664 (ret = mbedtls_ssl_flight_transmit(ssl)) != 0) {
3665 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_flight_transmit", ret);
3666 return ret;
Manuel Pégourié-Gonnard87a346f2017-09-13 12:45:21 +02003667 }
3668#endif
3669
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003670 MBEDTLS_SSL_DEBUG_MSG(2, ("<= write finished"));
Paul Bakker5121ce52009-01-03 21:22:43 +00003671
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003672 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +00003673}
3674
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003675#if defined(MBEDTLS_SSL_PROTO_SSL3)
Manuel Pégourié-Gonnardca6440b2014-09-10 12:39:54 +00003676#define SSL_MAX_HASH_LEN 36
3677#else
3678#define SSL_MAX_HASH_LEN 12
3679#endif
3680
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003681int mbedtls_ssl_parse_finished(mbedtls_ssl_context *ssl)
Paul Bakker5121ce52009-01-03 21:22:43 +00003682{
Janos Follath865b3eb2019-12-16 11:46:15 +00003683 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard879a4f92014-07-11 22:31:12 +02003684 unsigned int hash_len;
Manuel Pégourié-Gonnardca6440b2014-09-10 12:39:54 +00003685 unsigned char buf[SSL_MAX_HASH_LEN];
Paul Bakker5121ce52009-01-03 21:22:43 +00003686
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003687 MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse finished"));
Paul Bakker5121ce52009-01-03 21:22:43 +00003688
Gilles Peskine622d8042021-12-13 14:38:40 +01003689 /* There is currently no ciphersuite using another length with TLS 1.2 */
3690#if defined(MBEDTLS_SSL_PROTO_SSL3)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003691 if (ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0) {
Gilles Peskine622d8042021-12-13 14:38:40 +01003692 hash_len = 36;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003693 } else
Gilles Peskine622d8042021-12-13 14:38:40 +01003694#endif
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003695 hash_len = 12;
Gilles Peskine622d8042021-12-13 14:38:40 +01003696
David Horstmann2b857292025-03-11 18:13:02 +00003697 ret = ssl->handshake->calc_finished(ssl, buf, ssl->conf->endpoint ^ 1);
3698 if (ret != 0) {
3699 MBEDTLS_SSL_DEBUG_RET(1, "calc_finished", ret);
3700 goto exit;
3701 }
Paul Bakker5121ce52009-01-03 21:22:43 +00003702
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003703 if ((ret = mbedtls_ssl_read_record(ssl, 1)) != 0) {
3704 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_read_record", ret);
Gilles Peskinef91b2e52021-12-13 12:36:15 +01003705 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00003706 }
3707
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003708 if (ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE) {
3709 MBEDTLS_SSL_DEBUG_MSG(1, ("bad finished message"));
3710 mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
3711 MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE);
Gilles Peskinef91b2e52021-12-13 12:36:15 +01003712 ret = MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
3713 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00003714 }
3715
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003716 if (ssl->in_msg[0] != MBEDTLS_SSL_HS_FINISHED ||
3717 ssl->in_hslen != mbedtls_ssl_hs_hdr_len(ssl) + hash_len) {
3718 MBEDTLS_SSL_DEBUG_MSG(1, ("bad finished message"));
3719 mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
3720 MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
Gilles Peskinef91b2e52021-12-13 12:36:15 +01003721 ret = MBEDTLS_ERR_SSL_BAD_HS_FINISHED;
3722 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00003723 }
3724
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003725 if (mbedtls_ct_memcmp(ssl->in_msg + mbedtls_ssl_hs_hdr_len(ssl),
3726 buf, hash_len) != 0) {
3727 MBEDTLS_SSL_DEBUG_MSG(1, ("bad finished message"));
3728 mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
3729 MBEDTLS_SSL_ALERT_MSG_DECRYPT_ERROR);
Gilles Peskinef91b2e52021-12-13 12:36:15 +01003730 ret = MBEDTLS_ERR_SSL_BAD_HS_FINISHED;
3731 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00003732 }
3733
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003734#if defined(MBEDTLS_SSL_RENEGOTIATION)
Paul Bakker48916f92012-09-16 19:57:18 +00003735 ssl->verify_data_len = hash_len;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003736 memcpy(ssl->peer_verify_data, buf, hash_len);
Manuel Pégourié-Gonnard615e6772014-11-03 08:23:14 +01003737#endif
Paul Bakker48916f92012-09-16 19:57:18 +00003738
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003739 if (ssl->handshake->resume != 0) {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003740#if defined(MBEDTLS_SSL_CLI_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003741 if (ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT) {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003742 ssl->state = MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003743 }
Manuel Pégourié-Gonnardd16d1cb2014-11-20 18:15:05 +01003744#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003745#if defined(MBEDTLS_SSL_SRV_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003746 if (ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER) {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003747 ssl->state = MBEDTLS_SSL_HANDSHAKE_WRAPUP;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003748 }
Manuel Pégourié-Gonnardd16d1cb2014-11-20 18:15:05 +01003749#endif
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003750 } else {
Paul Bakker5121ce52009-01-03 21:22:43 +00003751 ssl->state++;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003752 }
Paul Bakker5121ce52009-01-03 21:22:43 +00003753
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003754#if defined(MBEDTLS_SSL_PROTO_DTLS)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003755 if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
3756 mbedtls_ssl_recv_flight_completed(ssl);
3757 }
Manuel Pégourié-Gonnard5d8ba532014-09-19 15:09:21 +02003758#endif
3759
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003760 MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse finished"));
Paul Bakker5121ce52009-01-03 21:22:43 +00003761
Gilles Peskinef91b2e52021-12-13 12:36:15 +01003762exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003763 mbedtls_platform_zeroize(buf, hash_len);
3764 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00003765}
3766
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003767static void ssl_handshake_params_init(mbedtls_ssl_handshake_params *handshake)
Paul Bakkeraccaffe2014-06-26 13:37:14 +02003768{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003769 memset(handshake, 0, sizeof(mbedtls_ssl_handshake_params));
Paul Bakkeraccaffe2014-06-26 13:37:14 +02003770
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003771#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
3772 defined(MBEDTLS_SSL_PROTO_TLS1_1)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003773 mbedtls_md5_init(&handshake->fin_md5);
3774 mbedtls_sha1_init(&handshake->fin_sha1);
3775 mbedtls_md5_starts_ret(&handshake->fin_md5);
3776 mbedtls_sha1_starts_ret(&handshake->fin_sha1);
Paul Bakkeraccaffe2014-06-26 13:37:14 +02003777#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003778#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
3779#if defined(MBEDTLS_SHA256_C)
Andrzej Kurekeb342242019-01-29 09:14:33 -05003780#if defined(MBEDTLS_USE_PSA_CRYPTO)
3781 handshake->fin_sha256_psa = psa_hash_operation_init();
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003782 psa_hash_setup(&handshake->fin_sha256_psa, PSA_ALG_SHA_256);
Andrzej Kurekeb342242019-01-29 09:14:33 -05003783#else
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003784 mbedtls_sha256_init(&handshake->fin_sha256);
3785 mbedtls_sha256_starts_ret(&handshake->fin_sha256, 0);
Paul Bakkeraccaffe2014-06-26 13:37:14 +02003786#endif
Andrzej Kurekeb342242019-01-29 09:14:33 -05003787#endif
Gilles Peskined2d59372021-05-12 22:43:27 +02003788#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384)
Andrzej Kurekeb342242019-01-29 09:14:33 -05003789#if defined(MBEDTLS_USE_PSA_CRYPTO)
Andrzej Kurek972fba52019-01-30 03:29:12 -05003790 handshake->fin_sha384_psa = psa_hash_operation_init();
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003791 psa_hash_setup(&handshake->fin_sha384_psa, PSA_ALG_SHA_384);
Andrzej Kurekeb342242019-01-29 09:14:33 -05003792#else
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003793 mbedtls_sha512_init(&handshake->fin_sha512);
3794 mbedtls_sha512_starts_ret(&handshake->fin_sha512, 1);
Paul Bakkeraccaffe2014-06-26 13:37:14 +02003795#endif
Andrzej Kurekeb342242019-01-29 09:14:33 -05003796#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003797#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
Paul Bakkeraccaffe2014-06-26 13:37:14 +02003798
3799 handshake->update_checksum = ssl_update_checksum_start;
Hanno Becker7e5437a2017-04-28 17:15:26 +01003800
3801#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
Gilles Peskineeccd8882020-03-10 12:19:08 +01003802 defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003803 mbedtls_ssl_sig_hash_set_init(&handshake->hash_algs);
Hanno Becker7e5437a2017-04-28 17:15:26 +01003804#endif
Paul Bakkeraccaffe2014-06-26 13:37:14 +02003805
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003806#if defined(MBEDTLS_DHM_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003807 mbedtls_dhm_init(&handshake->dhm_ctx);
Paul Bakkeraccaffe2014-06-26 13:37:14 +02003808#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003809#if defined(MBEDTLS_ECDH_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003810 mbedtls_ecdh_init(&handshake->ecdh_ctx);
Paul Bakkeraccaffe2014-06-26 13:37:14 +02003811#endif
Manuel Pégourié-Gonnardeef142d2015-09-16 10:05:04 +02003812#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003813 mbedtls_ecjpake_init(&handshake->ecjpake_ctx);
Manuel Pégourié-Gonnard77c06462015-09-17 13:59:49 +02003814#if defined(MBEDTLS_SSL_CLI_C)
3815 handshake->ecjpake_cache = NULL;
3816 handshake->ecjpake_cache_len = 0;
3817#endif
Manuel Pégourié-Gonnard76cfd3f2015-09-15 12:10:54 +02003818#endif
Manuel Pégourié-Gonnardcdc26ae2015-06-19 12:16:31 +02003819
Gilles Peskineeccd8882020-03-10 12:19:08 +01003820#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003821 mbedtls_x509_crt_restart_init(&handshake->ecrs_ctx);
Manuel Pégourié-Gonnard862cde52017-05-17 11:56:15 +02003822#endif
3823
Manuel Pégourié-Gonnardcdc26ae2015-06-19 12:16:31 +02003824#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
3825 handshake->sni_authmode = MBEDTLS_SSL_VERIFY_UNSET;
3826#endif
Hanno Becker75173122019-02-06 16:18:31 +00003827
3828#if defined(MBEDTLS_X509_CRT_PARSE_C) && \
3829 !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003830 mbedtls_pk_init(&handshake->peer_pubkey);
Hanno Becker75173122019-02-06 16:18:31 +00003831#endif
Paul Bakkeraccaffe2014-06-26 13:37:14 +02003832}
3833
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003834void mbedtls_ssl_transform_init(mbedtls_ssl_transform *transform)
Paul Bakkeraccaffe2014-06-26 13:37:14 +02003835{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003836 memset(transform, 0, sizeof(mbedtls_ssl_transform));
Paul Bakker84bbeb52014-07-01 14:53:22 +02003837
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003838 mbedtls_cipher_init(&transform->cipher_ctx_enc);
3839 mbedtls_cipher_init(&transform->cipher_ctx_dec);
Paul Bakker84bbeb52014-07-01 14:53:22 +02003840
Hanno Beckerd56ed242018-01-03 15:32:51 +00003841#if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003842 mbedtls_md_init(&transform->md_ctx_enc);
3843 mbedtls_md_init(&transform->md_ctx_dec);
Hanno Beckerd56ed242018-01-03 15:32:51 +00003844#endif
Paul Bakkeraccaffe2014-06-26 13:37:14 +02003845}
3846
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003847void mbedtls_ssl_session_init(mbedtls_ssl_session *session)
Paul Bakkeraccaffe2014-06-26 13:37:14 +02003848{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003849 memset(session, 0, sizeof(mbedtls_ssl_session));
Paul Bakkeraccaffe2014-06-26 13:37:14 +02003850}
3851
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +02003852MBEDTLS_CHECK_RETURN_CRITICAL
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003853static int ssl_handshake_init(mbedtls_ssl_context *ssl)
Paul Bakker48916f92012-09-16 19:57:18 +00003854{
Paul Bakkeraccaffe2014-06-26 13:37:14 +02003855 /* Clear old handshake information if present */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003856 if (ssl->transform_negotiate) {
3857 mbedtls_ssl_transform_free(ssl->transform_negotiate);
3858 }
3859 if (ssl->session_negotiate) {
3860 mbedtls_ssl_session_free(ssl->session_negotiate);
3861 }
3862 if (ssl->handshake) {
3863 mbedtls_ssl_handshake_free(ssl);
3864 }
Paul Bakkeraccaffe2014-06-26 13:37:14 +02003865
3866 /*
3867 * Either the pointers are now NULL or cleared properly and can be freed.
3868 * Now allocate missing structures.
3869 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003870 if (ssl->transform_negotiate == NULL) {
3871 ssl->transform_negotiate = mbedtls_calloc(1, sizeof(mbedtls_ssl_transform));
Paul Bakkerb9cfaa02013-10-11 18:58:55 +02003872 }
Paul Bakker48916f92012-09-16 19:57:18 +00003873
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003874 if (ssl->session_negotiate == NULL) {
3875 ssl->session_negotiate = mbedtls_calloc(1, sizeof(mbedtls_ssl_session));
Paul Bakkerb9cfaa02013-10-11 18:58:55 +02003876 }
Paul Bakker48916f92012-09-16 19:57:18 +00003877
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003878 if (ssl->handshake == NULL) {
3879 ssl->handshake = mbedtls_calloc(1, sizeof(mbedtls_ssl_handshake_params));
Paul Bakkerb9cfaa02013-10-11 18:58:55 +02003880 }
Andrzej Kurek0afa2a12020-03-03 10:39:58 -05003881#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
3882 /* If the buffers are too small - reallocate */
Andrzej Kurek8ea68722020-04-03 06:40:47 -04003883
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003884 handle_buffer_resizing(ssl, 0, MBEDTLS_SSL_IN_BUFFER_LEN,
3885 MBEDTLS_SSL_OUT_BUFFER_LEN);
Andrzej Kurek0afa2a12020-03-03 10:39:58 -05003886#endif
Paul Bakker48916f92012-09-16 19:57:18 +00003887
Paul Bakkeraccaffe2014-06-26 13:37:14 +02003888 /* All pointers should exist and can be directly freed without issue */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003889 if (ssl->handshake == NULL ||
Paul Bakker48916f92012-09-16 19:57:18 +00003890 ssl->transform_negotiate == NULL ||
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003891 ssl->session_negotiate == NULL) {
3892 MBEDTLS_SSL_DEBUG_MSG(1, ("alloc() of ssl sub-contexts failed"));
Paul Bakkeraccaffe2014-06-26 13:37:14 +02003893
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003894 mbedtls_free(ssl->handshake);
3895 mbedtls_free(ssl->transform_negotiate);
3896 mbedtls_free(ssl->session_negotiate);
Paul Bakkeraccaffe2014-06-26 13:37:14 +02003897
3898 ssl->handshake = NULL;
3899 ssl->transform_negotiate = NULL;
3900 ssl->session_negotiate = NULL;
3901
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003902 return MBEDTLS_ERR_SSL_ALLOC_FAILED;
Paul Bakker48916f92012-09-16 19:57:18 +00003903 }
3904
Paul Bakkeraccaffe2014-06-26 13:37:14 +02003905 /* Initialize structures */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003906 mbedtls_ssl_session_init(ssl->session_negotiate);
3907 mbedtls_ssl_transform_init(ssl->transform_negotiate);
3908 ssl_handshake_params_init(ssl->handshake);
Paul Bakker968afaa2014-07-09 11:09:24 +02003909
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003910#if defined(MBEDTLS_SSL_PROTO_DTLS)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003911 if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
Manuel Pégourié-Gonnard06939ce2015-05-11 11:25:46 +02003912 ssl->handshake->alt_transform_out = ssl->transform_out;
Manuel Pégourié-Gonnard5d8ba532014-09-19 15:09:21 +02003913
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003914 if (ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT) {
Manuel Pégourié-Gonnard06939ce2015-05-11 11:25:46 +02003915 ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_PREPARING;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003916 } else {
Manuel Pégourié-Gonnard06939ce2015-05-11 11:25:46 +02003917 ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_WAITING;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003918 }
Manuel Pégourié-Gonnard286a1362015-05-13 16:22:05 +02003919
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003920 mbedtls_ssl_set_timer(ssl, 0);
Manuel Pégourié-Gonnard06939ce2015-05-11 11:25:46 +02003921 }
Manuel Pégourié-Gonnard5d8ba532014-09-19 15:09:21 +02003922#endif
3923
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003924 return 0;
Paul Bakker48916f92012-09-16 19:57:18 +00003925}
3926
Manuel Pégourié-Gonnarde057d3b2015-05-20 10:59:43 +02003927#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C)
Manuel Pégourié-Gonnard7d38d212014-07-23 17:52:09 +02003928/* Dummy cookie callbacks for defaults */
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +02003929MBEDTLS_CHECK_RETURN_CRITICAL
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003930static int ssl_cookie_write_dummy(void *ctx,
3931 unsigned char **p, unsigned char *end,
3932 const unsigned char *cli_id, size_t cli_id_len)
Manuel Pégourié-Gonnard7d38d212014-07-23 17:52:09 +02003933{
3934 ((void) ctx);
3935 ((void) p);
3936 ((void) end);
3937 ((void) cli_id);
3938 ((void) cli_id_len);
3939
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003940 return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
Manuel Pégourié-Gonnard7d38d212014-07-23 17:52:09 +02003941}
3942
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +02003943MBEDTLS_CHECK_RETURN_CRITICAL
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003944static int ssl_cookie_check_dummy(void *ctx,
3945 const unsigned char *cookie, size_t cookie_len,
3946 const unsigned char *cli_id, size_t cli_id_len)
Manuel Pégourié-Gonnard7d38d212014-07-23 17:52:09 +02003947{
3948 ((void) ctx);
3949 ((void) cookie);
3950 ((void) cookie_len);
3951 ((void) cli_id);
3952 ((void) cli_id_len);
3953
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003954 return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
Manuel Pégourié-Gonnard7d38d212014-07-23 17:52:09 +02003955}
Manuel Pégourié-Gonnarde057d3b2015-05-20 10:59:43 +02003956#endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY && MBEDTLS_SSL_SRV_C */
Manuel Pégourié-Gonnard7d38d212014-07-23 17:52:09 +02003957
Paul Bakker5121ce52009-01-03 21:22:43 +00003958/*
3959 * Initialize an SSL context
3960 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003961void mbedtls_ssl_init(mbedtls_ssl_context *ssl)
Manuel Pégourié-Gonnard41d479e2015-04-29 00:48:22 +02003962{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003963 memset(ssl, 0, sizeof(mbedtls_ssl_context));
Manuel Pégourié-Gonnard41d479e2015-04-29 00:48:22 +02003964}
3965
3966/*
3967 * Setup an SSL context
3968 */
Hanno Becker2a43f6f2018-08-10 11:12:52 +01003969
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003970int mbedtls_ssl_setup(mbedtls_ssl_context *ssl,
3971 const mbedtls_ssl_config *conf)
Paul Bakker5121ce52009-01-03 21:22:43 +00003972{
Janos Follath865b3eb2019-12-16 11:46:15 +00003973 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Darryl Greenb33cc762019-11-28 14:29:44 +00003974 size_t in_buf_len = MBEDTLS_SSL_IN_BUFFER_LEN;
3975 size_t out_buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN;
Paul Bakker5121ce52009-01-03 21:22:43 +00003976
Manuel Pégourié-Gonnarddef0bbe2015-05-04 14:56:36 +02003977 ssl->conf = conf;
Paul Bakker62f2dee2012-09-28 07:31:51 +00003978
3979 /*
Manuel Pégourié-Gonnard06193482014-02-14 08:39:32 +01003980 * Prepare base structures
Paul Bakker62f2dee2012-09-28 07:31:51 +00003981 */
k-stachowiakc9a5f022018-07-24 13:53:31 +02003982
3983 /* Set to NULL in case of an error condition */
3984 ssl->out_buf = NULL;
k-stachowiaka47911c2018-07-04 17:41:58 +02003985
Darryl Greenb33cc762019-11-28 14:29:44 +00003986#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
3987 ssl->in_buf_len = in_buf_len;
3988#endif
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003989 ssl->in_buf = mbedtls_calloc(1, in_buf_len);
3990 if (ssl->in_buf == NULL) {
3991 MBEDTLS_SSL_DEBUG_MSG(1, ("alloc(%" MBEDTLS_PRINTF_SIZET " bytes) failed", in_buf_len));
k-stachowiak9f7798e2018-07-31 16:52:32 +02003992 ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
k-stachowiaka47911c2018-07-04 17:41:58 +02003993 goto error;
Angus Grattond8213d02016-05-25 20:56:48 +10003994 }
3995
Darryl Greenb33cc762019-11-28 14:29:44 +00003996#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
3997 ssl->out_buf_len = out_buf_len;
3998#endif
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003999 ssl->out_buf = mbedtls_calloc(1, out_buf_len);
4000 if (ssl->out_buf == NULL) {
4001 MBEDTLS_SSL_DEBUG_MSG(1, ("alloc(%" MBEDTLS_PRINTF_SIZET " bytes) failed", out_buf_len));
k-stachowiak9f7798e2018-07-31 16:52:32 +02004002 ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
k-stachowiaka47911c2018-07-04 17:41:58 +02004003 goto error;
Paul Bakker5121ce52009-01-03 21:22:43 +00004004 }
4005
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004006 mbedtls_ssl_reset_in_out_pointers(ssl);
Manuel Pégourié-Gonnard419d5ae2015-05-04 19:32:36 +02004007
Johan Pascalb62bb512015-12-03 21:56:45 +01004008#if defined(MBEDTLS_SSL_DTLS_SRTP)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004009 memset(&ssl->dtls_srtp_info, 0, sizeof(ssl->dtls_srtp_info));
Johan Pascalb62bb512015-12-03 21:56:45 +01004010#endif
4011
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004012 if ((ret = ssl_handshake_init(ssl)) != 0) {
k-stachowiaka47911c2018-07-04 17:41:58 +02004013 goto error;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004014 }
Paul Bakker5121ce52009-01-03 21:22:43 +00004015
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004016 return 0;
k-stachowiaka47911c2018-07-04 17:41:58 +02004017
4018error:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004019 mbedtls_free(ssl->in_buf);
4020 mbedtls_free(ssl->out_buf);
k-stachowiaka47911c2018-07-04 17:41:58 +02004021
4022 ssl->conf = NULL;
4023
Darryl Greenb33cc762019-11-28 14:29:44 +00004024#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
4025 ssl->in_buf_len = 0;
4026 ssl->out_buf_len = 0;
4027#endif
k-stachowiaka47911c2018-07-04 17:41:58 +02004028 ssl->in_buf = NULL;
4029 ssl->out_buf = NULL;
4030
4031 ssl->in_hdr = NULL;
4032 ssl->in_ctr = NULL;
4033 ssl->in_len = NULL;
4034 ssl->in_iv = NULL;
4035 ssl->in_msg = NULL;
4036
4037 ssl->out_hdr = NULL;
4038 ssl->out_ctr = NULL;
4039 ssl->out_len = NULL;
4040 ssl->out_iv = NULL;
4041 ssl->out_msg = NULL;
4042
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004043 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00004044}
4045
4046/*
Paul Bakker7eb013f2011-10-06 12:37:39 +00004047 * Reset an initialized and used SSL context for re-use while retaining
4048 * all application-set variables, function pointers and data.
Manuel Pégourié-Gonnard3f09b6d2015-09-08 11:58:14 +02004049 *
4050 * If partial is non-zero, keep data in the input buffer and client ID.
4051 * (Use when a DTLS client reconnects from the same port.)
Paul Bakker7eb013f2011-10-06 12:37:39 +00004052 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004053int mbedtls_ssl_session_reset_int(mbedtls_ssl_context *ssl, int partial)
Paul Bakker7eb013f2011-10-06 12:37:39 +00004054{
Janos Follath865b3eb2019-12-16 11:46:15 +00004055 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Darryl Greenb33cc762019-11-28 14:29:44 +00004056#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
4057 size_t in_buf_len = ssl->in_buf_len;
4058 size_t out_buf_len = ssl->out_buf_len;
4059#else
4060 size_t in_buf_len = MBEDTLS_SSL_IN_BUFFER_LEN;
4061 size_t out_buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN;
4062#endif
Paul Bakker48916f92012-09-16 19:57:18 +00004063
Hanno Becker7e772132018-08-10 12:38:21 +01004064#if !defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) || \
4065 !defined(MBEDTLS_SSL_SRV_C)
4066 ((void) partial);
4067#endif
4068
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004069 ssl->state = MBEDTLS_SSL_HELLO_REQUEST;
Manuel Pégourié-Gonnard615e6772014-11-03 08:23:14 +01004070
Manuel Pégourié-Gonnard286a1362015-05-13 16:22:05 +02004071 /* Cancel any possibly running timer */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004072 mbedtls_ssl_set_timer(ssl, 0);
Manuel Pégourié-Gonnard286a1362015-05-13 16:22:05 +02004073
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004074#if defined(MBEDTLS_SSL_RENEGOTIATION)
4075 ssl->renego_status = MBEDTLS_SSL_INITIAL_HANDSHAKE;
Manuel Pégourié-Gonnard615e6772014-11-03 08:23:14 +01004076 ssl->renego_records_seen = 0;
Paul Bakker48916f92012-09-16 19:57:18 +00004077
4078 ssl->verify_data_len = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004079 memset(ssl->own_verify_data, 0, MBEDTLS_SSL_VERIFY_DATA_MAX_LEN);
4080 memset(ssl->peer_verify_data, 0, MBEDTLS_SSL_VERIFY_DATA_MAX_LEN);
Manuel Pégourié-Gonnard615e6772014-11-03 08:23:14 +01004081#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004082 ssl->secure_renegotiation = MBEDTLS_SSL_LEGACY_RENEGOTIATION;
Paul Bakker48916f92012-09-16 19:57:18 +00004083
Paul Bakker7eb013f2011-10-06 12:37:39 +00004084 ssl->in_offt = NULL;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004085 mbedtls_ssl_reset_in_out_pointers(ssl);
Paul Bakker7eb013f2011-10-06 12:37:39 +00004086
4087 ssl->in_msgtype = 0;
4088 ssl->in_msglen = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004089#if defined(MBEDTLS_SSL_PROTO_DTLS)
Manuel Pégourié-Gonnardb2f3be82014-07-10 17:54:52 +02004090 ssl->next_record_offset = 0;
Manuel Pégourié-Gonnard246c13a2014-09-24 13:56:09 +02004091 ssl->in_epoch = 0;
Manuel Pégourié-Gonnardb2f3be82014-07-10 17:54:52 +02004092#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004093#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004094 mbedtls_ssl_dtls_replay_reset(ssl);
Manuel Pégourié-Gonnardb47368a2014-09-24 13:29:58 +02004095#endif
Paul Bakker7eb013f2011-10-06 12:37:39 +00004096
4097 ssl->in_hslen = 0;
4098 ssl->nb_zero = 0;
Hanno Beckeraf0665d2017-05-24 09:16:26 +01004099
4100 ssl->keep_current_message = 0;
Paul Bakker7eb013f2011-10-06 12:37:39 +00004101
4102 ssl->out_msgtype = 0;
4103 ssl->out_msglen = 0;
4104 ssl->out_left = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004105#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004106 if (ssl->split_done != MBEDTLS_SSL_CBC_RECORD_SPLITTING_DISABLED) {
Manuel Pégourié-Gonnardcfa477e2015-01-07 14:50:54 +01004107 ssl->split_done = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004108 }
Manuel Pégourié-Gonnardd76314c2015-01-07 12:39:44 +01004109#endif
Paul Bakker7eb013f2011-10-06 12:37:39 +00004110
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004111 memset(ssl->cur_out_ctr, 0, sizeof(ssl->cur_out_ctr));
Hanno Becker19859472018-08-06 09:40:20 +01004112
Paul Bakker48916f92012-09-16 19:57:18 +00004113 ssl->transform_in = NULL;
4114 ssl->transform_out = NULL;
Paul Bakker7eb013f2011-10-06 12:37:39 +00004115
Hanno Becker78640902018-08-13 16:35:15 +01004116 ssl->session_in = NULL;
4117 ssl->session_out = NULL;
4118
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004119 memset(ssl->out_buf, 0, out_buf_len);
Hanno Becker4ccbf062018-08-10 11:20:38 +01004120
David Horstmannd4f22082022-10-26 18:25:14 +01004121 int clear_in_buf = 1;
Hanno Becker4ccbf062018-08-10 11:20:38 +01004122#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004123 if (partial != 0) {
David Horstmannd4f22082022-10-26 18:25:14 +01004124 clear_in_buf = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004125 }
Hanno Becker4ccbf062018-08-10 11:20:38 +01004126#endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE && MBEDTLS_SSL_SRV_C */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004127 if (clear_in_buf) {
Hanno Becker4ccbf062018-08-10 11:20:38 +01004128 ssl->in_left = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004129 memset(ssl->in_buf, 0, in_buf_len);
Hanno Becker4ccbf062018-08-10 11:20:38 +01004130 }
Paul Bakker05ef8352012-05-08 09:17:57 +00004131
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004132#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004133 if (mbedtls_ssl_hw_record_reset != NULL) {
4134 MBEDTLS_SSL_DEBUG_MSG(2, ("going for mbedtls_ssl_hw_record_reset()"));
4135 if ((ret = mbedtls_ssl_hw_record_reset(ssl)) != 0) {
4136 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_hw_record_reset", ret);
4137 return MBEDTLS_ERR_SSL_HW_ACCEL_FAILED;
Paul Bakker2770fbd2012-07-03 13:30:23 +00004138 }
Paul Bakker05ef8352012-05-08 09:17:57 +00004139 }
4140#endif
Paul Bakker2770fbd2012-07-03 13:30:23 +00004141
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004142 if (ssl->transform) {
4143 mbedtls_ssl_transform_free(ssl->transform);
4144 mbedtls_free(ssl->transform);
Paul Bakker48916f92012-09-16 19:57:18 +00004145 ssl->transform = NULL;
Paul Bakker2770fbd2012-07-03 13:30:23 +00004146 }
Paul Bakker48916f92012-09-16 19:57:18 +00004147
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004148 if (ssl->session) {
4149 mbedtls_ssl_session_free(ssl->session);
4150 mbedtls_free(ssl->session);
Paul Bakkerc0463502013-02-14 11:19:38 +01004151 ssl->session = NULL;
4152 }
4153
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004154#if defined(MBEDTLS_SSL_ALPN)
Manuel Pégourié-Gonnard7e250d42014-04-04 16:08:41 +02004155 ssl->alpn_chosen = NULL;
4156#endif
4157
Manuel Pégourié-Gonnarde057d3b2015-05-20 10:59:43 +02004158#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C)
David Horstmannb5b1ed22022-10-27 13:21:49 +01004159 int free_cli_id = 1;
Hanno Becker4ccbf062018-08-10 11:20:38 +01004160#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004161 if (partial != 0) {
David Horstmannd4f22082022-10-26 18:25:14 +01004162 free_cli_id = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004163 }
Hanno Becker4ccbf062018-08-10 11:20:38 +01004164#endif
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004165 if (free_cli_id) {
4166 mbedtls_free(ssl->cli_id);
Manuel Pégourié-Gonnard3f09b6d2015-09-08 11:58:14 +02004167 ssl->cli_id = NULL;
4168 ssl->cli_id_len = 0;
4169 }
Manuel Pégourié-Gonnard43c02182014-07-22 17:32:01 +02004170#endif
4171
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004172 if ((ret = ssl_handshake_init(ssl)) != 0) {
4173 return ret;
4174 }
Paul Bakker2770fbd2012-07-03 13:30:23 +00004175
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004176 return 0;
Paul Bakker7eb013f2011-10-06 12:37:39 +00004177}
4178
Manuel Pégourié-Gonnard779e4292013-08-03 13:50:48 +02004179/*
Manuel Pégourié-Gonnard3f09b6d2015-09-08 11:58:14 +02004180 * Reset an initialized and used SSL context for re-use while retaining
4181 * all application-set variables, function pointers and data.
4182 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004183int mbedtls_ssl_session_reset(mbedtls_ssl_context *ssl)
Manuel Pégourié-Gonnard3f09b6d2015-09-08 11:58:14 +02004184{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004185 return mbedtls_ssl_session_reset_int(ssl, 0);
Manuel Pégourié-Gonnard3f09b6d2015-09-08 11:58:14 +02004186}
4187
4188/*
Paul Bakker5121ce52009-01-03 21:22:43 +00004189 * SSL set accessors
4190 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004191void mbedtls_ssl_conf_endpoint(mbedtls_ssl_config *conf, int endpoint)
Paul Bakker5121ce52009-01-03 21:22:43 +00004192{
Manuel Pégourié-Gonnardd36e33f2015-05-05 10:45:39 +02004193 conf->endpoint = endpoint;
Paul Bakker5121ce52009-01-03 21:22:43 +00004194}
4195
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004196void mbedtls_ssl_conf_transport(mbedtls_ssl_config *conf, int transport)
Manuel Pégourié-Gonnard0b1ff292014-02-06 13:04:16 +01004197{
Manuel Pégourié-Gonnardd36e33f2015-05-05 10:45:39 +02004198 conf->transport = transport;
Manuel Pégourié-Gonnard0b1ff292014-02-06 13:04:16 +01004199}
4200
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004201#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004202void mbedtls_ssl_conf_dtls_anti_replay(mbedtls_ssl_config *conf, char mode)
Manuel Pégourié-Gonnard27393132014-09-24 14:41:11 +02004203{
Manuel Pégourié-Gonnardd36e33f2015-05-05 10:45:39 +02004204 conf->anti_replay = mode;
Manuel Pégourié-Gonnard27393132014-09-24 14:41:11 +02004205}
4206#endif
4207
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004208#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004209void mbedtls_ssl_conf_dtls_badmac_limit(mbedtls_ssl_config *conf, unsigned limit)
Manuel Pégourié-Gonnardb0643d12014-10-14 18:30:36 +02004210{
Manuel Pégourié-Gonnardd36e33f2015-05-05 10:45:39 +02004211 conf->badmac_limit = limit;
Manuel Pégourié-Gonnardb0643d12014-10-14 18:30:36 +02004212}
4213#endif
4214
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004215#if defined(MBEDTLS_SSL_PROTO_DTLS)
Hanno Becker04da1892018-08-14 13:22:10 +01004216
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004217void mbedtls_ssl_set_datagram_packing(mbedtls_ssl_context *ssl,
4218 unsigned allow_packing)
Hanno Becker04da1892018-08-14 13:22:10 +01004219{
4220 ssl->disable_datagram_packing = !allow_packing;
4221}
4222
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004223void mbedtls_ssl_conf_handshake_timeout(mbedtls_ssl_config *conf,
4224 uint32_t min, uint32_t max)
Manuel Pégourié-Gonnard905dd242014-10-01 12:03:55 +02004225{
Manuel Pégourié-Gonnardd36e33f2015-05-05 10:45:39 +02004226 conf->hs_timeout_min = min;
4227 conf->hs_timeout_max = max;
Manuel Pégourié-Gonnard905dd242014-10-01 12:03:55 +02004228}
4229#endif
4230
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004231void mbedtls_ssl_conf_authmode(mbedtls_ssl_config *conf, int authmode)
Paul Bakker5121ce52009-01-03 21:22:43 +00004232{
Manuel Pégourié-Gonnardd36e33f2015-05-05 10:45:39 +02004233 conf->authmode = authmode;
Paul Bakker5121ce52009-01-03 21:22:43 +00004234}
4235
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004236#if defined(MBEDTLS_X509_CRT_PARSE_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004237void mbedtls_ssl_conf_verify(mbedtls_ssl_config *conf,
4238 int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
4239 void *p_vrfy)
Paul Bakkerb63b0af2011-01-13 17:54:59 +00004240{
Manuel Pégourié-Gonnardd36e33f2015-05-05 10:45:39 +02004241 conf->f_vrfy = f_vrfy;
4242 conf->p_vrfy = p_vrfy;
Paul Bakkerb63b0af2011-01-13 17:54:59 +00004243}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004244#endif /* MBEDTLS_X509_CRT_PARSE_C */
Paul Bakkerb63b0af2011-01-13 17:54:59 +00004245
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004246void mbedtls_ssl_conf_rng(mbedtls_ssl_config *conf,
4247 int (*f_rng)(void *, unsigned char *, size_t),
4248 void *p_rng)
Paul Bakker5121ce52009-01-03 21:22:43 +00004249{
Manuel Pégourié-Gonnard750e4d72015-05-07 12:35:38 +01004250 conf->f_rng = f_rng;
4251 conf->p_rng = p_rng;
Paul Bakker5121ce52009-01-03 21:22:43 +00004252}
4253
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004254void mbedtls_ssl_conf_dbg(mbedtls_ssl_config *conf,
4255 void (*f_dbg)(void *, int, const char *, int, const char *),
4256 void *p_dbg)
Paul Bakker5121ce52009-01-03 21:22:43 +00004257{
Manuel Pégourié-Gonnardd36e33f2015-05-05 10:45:39 +02004258 conf->f_dbg = f_dbg;
4259 conf->p_dbg = p_dbg;
Paul Bakker5121ce52009-01-03 21:22:43 +00004260}
4261
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004262void mbedtls_ssl_set_bio(mbedtls_ssl_context *ssl,
4263 void *p_bio,
4264 mbedtls_ssl_send_t *f_send,
4265 mbedtls_ssl_recv_t *f_recv,
4266 mbedtls_ssl_recv_timeout_t *f_recv_timeout)
Manuel Pégourié-Gonnard8fa6dfd2014-09-17 10:47:43 +02004267{
4268 ssl->p_bio = p_bio;
4269 ssl->f_send = f_send;
4270 ssl->f_recv = f_recv;
4271 ssl->f_recv_timeout = f_recv_timeout;
Manuel Pégourié-Gonnard97fd52c2015-05-06 15:38:52 +01004272}
4273
Manuel Pégourié-Gonnard6e7aaca2018-08-20 10:37:23 +02004274#if defined(MBEDTLS_SSL_PROTO_DTLS)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004275void mbedtls_ssl_set_mtu(mbedtls_ssl_context *ssl, uint16_t mtu)
Manuel Pégourié-Gonnard6e7aaca2018-08-20 10:37:23 +02004276{
4277 ssl->mtu = mtu;
4278}
4279#endif
4280
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004281void mbedtls_ssl_conf_read_timeout(mbedtls_ssl_config *conf, uint32_t timeout)
Manuel Pégourié-Gonnard97fd52c2015-05-06 15:38:52 +01004282{
4283 conf->read_timeout = timeout;
Manuel Pégourié-Gonnard8fa6dfd2014-09-17 10:47:43 +02004284}
4285
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004286void mbedtls_ssl_set_timer_cb(mbedtls_ssl_context *ssl,
4287 void *p_timer,
4288 mbedtls_ssl_set_timer_t *f_set_timer,
4289 mbedtls_ssl_get_timer_t *f_get_timer)
Manuel Pégourié-Gonnard2e012912015-05-12 20:55:41 +02004290{
4291 ssl->p_timer = p_timer;
4292 ssl->f_set_timer = f_set_timer;
4293 ssl->f_get_timer = f_get_timer;
Manuel Pégourié-Gonnard286a1362015-05-13 16:22:05 +02004294
4295 /* Make sure we start with no timer running */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004296 mbedtls_ssl_set_timer(ssl, 0);
Manuel Pégourié-Gonnard2e012912015-05-12 20:55:41 +02004297}
4298
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004299#if defined(MBEDTLS_SSL_SRV_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004300void mbedtls_ssl_conf_session_cache(mbedtls_ssl_config *conf,
4301 void *p_cache,
4302 int (*f_get_cache)(void *, mbedtls_ssl_session *),
4303 int (*f_set_cache)(void *, const mbedtls_ssl_session *))
Paul Bakker5121ce52009-01-03 21:22:43 +00004304{
Manuel Pégourié-Gonnard5cb33082015-05-06 18:06:26 +01004305 conf->p_cache = p_cache;
Manuel Pégourié-Gonnardd36e33f2015-05-05 10:45:39 +02004306 conf->f_get_cache = f_get_cache;
Manuel Pégourié-Gonnardd36e33f2015-05-05 10:45:39 +02004307 conf->f_set_cache = f_set_cache;
Paul Bakker5121ce52009-01-03 21:22:43 +00004308}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004309#endif /* MBEDTLS_SSL_SRV_C */
Paul Bakker5121ce52009-01-03 21:22:43 +00004310
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004311#if defined(MBEDTLS_SSL_CLI_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004312int mbedtls_ssl_set_session(mbedtls_ssl_context *ssl, const mbedtls_ssl_session *session)
Paul Bakker5121ce52009-01-03 21:22:43 +00004313{
Janos Follath865b3eb2019-12-16 11:46:15 +00004314 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard06650f62013-08-02 15:34:52 +02004315
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004316 if (ssl == NULL ||
Manuel Pégourié-Gonnard06650f62013-08-02 15:34:52 +02004317 session == NULL ||
4318 ssl->session_negotiate == NULL ||
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004319 ssl->conf->endpoint != MBEDTLS_SSL_IS_CLIENT) {
4320 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
Manuel Pégourié-Gonnard06650f62013-08-02 15:34:52 +02004321 }
4322
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004323 if ((ret = mbedtls_ssl_session_copy(ssl->session_negotiate,
4324 session)) != 0) {
4325 return ret;
4326 }
Manuel Pégourié-Gonnard06650f62013-08-02 15:34:52 +02004327
Paul Bakker0a597072012-09-25 21:55:46 +00004328 ssl->handshake->resume = 1;
Manuel Pégourié-Gonnard06650f62013-08-02 15:34:52 +02004329
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004330 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +00004331}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004332#endif /* MBEDTLS_SSL_CLI_C */
Paul Bakker5121ce52009-01-03 21:22:43 +00004333
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004334void mbedtls_ssl_conf_ciphersuites(mbedtls_ssl_config *conf,
4335 const int *ciphersuites)
Paul Bakker5121ce52009-01-03 21:22:43 +00004336{
Manuel Pégourié-Gonnardd36e33f2015-05-05 10:45:39 +02004337 conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_0] = ciphersuites;
4338 conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_1] = ciphersuites;
4339 conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_2] = ciphersuites;
4340 conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_3] = ciphersuites;
Paul Bakker8f4ddae2013-04-15 15:09:54 +02004341}
4342
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004343void mbedtls_ssl_conf_ciphersuites_for_version(mbedtls_ssl_config *conf,
4344 const int *ciphersuites,
4345 int major, int minor)
Paul Bakker8f4ddae2013-04-15 15:09:54 +02004346{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004347 if (major != MBEDTLS_SSL_MAJOR_VERSION_3) {
Paul Bakker8f4ddae2013-04-15 15:09:54 +02004348 return;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004349 }
Paul Bakker8f4ddae2013-04-15 15:09:54 +02004350
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004351 if (minor < MBEDTLS_SSL_MINOR_VERSION_0 || minor > MBEDTLS_SSL_MINOR_VERSION_3) {
Paul Bakker8f4ddae2013-04-15 15:09:54 +02004352 return;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004353 }
Paul Bakker8f4ddae2013-04-15 15:09:54 +02004354
Manuel Pégourié-Gonnardd36e33f2015-05-05 10:45:39 +02004355 conf->ciphersuite_list[minor] = ciphersuites;
Paul Bakker5121ce52009-01-03 21:22:43 +00004356}
4357
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004358#if defined(MBEDTLS_X509_CRT_PARSE_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004359void mbedtls_ssl_conf_cert_profile(mbedtls_ssl_config *conf,
4360 const mbedtls_x509_crt_profile *profile)
Manuel Pégourié-Gonnard6e3ee3a2015-06-17 10:58:20 +02004361{
4362 conf->cert_profile = profile;
4363}
4364
Manuel Pégourié-Gonnard8f618a82015-05-10 21:13:36 +02004365/* Append a new keycert entry to a (possibly empty) list */
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +02004366MBEDTLS_CHECK_RETURN_CRITICAL
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004367static int ssl_append_key_cert(mbedtls_ssl_key_cert **head,
4368 mbedtls_x509_crt *cert,
4369 mbedtls_pk_context *key)
Manuel Pégourié-Gonnard834ea852013-09-23 14:46:13 +02004370{
niisato8ee24222018-06-25 19:05:48 +09004371 mbedtls_ssl_key_cert *new_cert;
Manuel Pégourié-Gonnard834ea852013-09-23 14:46:13 +02004372
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004373 new_cert = mbedtls_calloc(1, sizeof(mbedtls_ssl_key_cert));
4374 if (new_cert == NULL) {
4375 return MBEDTLS_ERR_SSL_ALLOC_FAILED;
4376 }
Manuel Pégourié-Gonnard834ea852013-09-23 14:46:13 +02004377
niisato8ee24222018-06-25 19:05:48 +09004378 new_cert->cert = cert;
4379 new_cert->key = key;
4380 new_cert->next = NULL;
Manuel Pégourié-Gonnard834ea852013-09-23 14:46:13 +02004381
Manuel Pégourié-Gonnard8f618a82015-05-10 21:13:36 +02004382 /* Update head is the list was null, else add to the end */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004383 if (*head == NULL) {
niisato8ee24222018-06-25 19:05:48 +09004384 *head = new_cert;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004385 } else {
Manuel Pégourié-Gonnard8f618a82015-05-10 21:13:36 +02004386 mbedtls_ssl_key_cert *cur = *head;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004387 while (cur->next != NULL) {
Manuel Pégourié-Gonnard8f618a82015-05-10 21:13:36 +02004388 cur = cur->next;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004389 }
niisato8ee24222018-06-25 19:05:48 +09004390 cur->next = new_cert;
Manuel Pégourié-Gonnard834ea852013-09-23 14:46:13 +02004391 }
4392
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004393 return 0;
Manuel Pégourié-Gonnard8f618a82015-05-10 21:13:36 +02004394}
4395
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004396int mbedtls_ssl_conf_own_cert(mbedtls_ssl_config *conf,
Manuel Pégourié-Gonnard8f618a82015-05-10 21:13:36 +02004397 mbedtls_x509_crt *own_cert,
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004398 mbedtls_pk_context *pk_key)
Manuel Pégourié-Gonnard8f618a82015-05-10 21:13:36 +02004399{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004400 return ssl_append_key_cert(&conf->key_cert, own_cert, pk_key);
Manuel Pégourié-Gonnard834ea852013-09-23 14:46:13 +02004401}
4402
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004403void mbedtls_ssl_conf_ca_chain(mbedtls_ssl_config *conf,
Manuel Pégourié-Gonnardbc2b7712015-05-06 11:14:19 +01004404 mbedtls_x509_crt *ca_chain,
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004405 mbedtls_x509_crl *ca_crl)
Paul Bakker5121ce52009-01-03 21:22:43 +00004406{
Manuel Pégourié-Gonnardbc2b7712015-05-06 11:14:19 +01004407 conf->ca_chain = ca_chain;
4408 conf->ca_crl = ca_crl;
Hanno Becker5adaad92019-03-27 16:54:37 +00004409
4410#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
4411 /* mbedtls_ssl_conf_ca_chain() and mbedtls_ssl_conf_ca_cb()
4412 * cannot be used together. */
4413 conf->f_ca_cb = NULL;
4414 conf->p_ca_cb = NULL;
4415#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */
Paul Bakker5121ce52009-01-03 21:22:43 +00004416}
Hanno Becker5adaad92019-03-27 16:54:37 +00004417
4418#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004419void mbedtls_ssl_conf_ca_cb(mbedtls_ssl_config *conf,
4420 mbedtls_x509_crt_ca_cb_t f_ca_cb,
4421 void *p_ca_cb)
Hanno Becker5adaad92019-03-27 16:54:37 +00004422{
4423 conf->f_ca_cb = f_ca_cb;
4424 conf->p_ca_cb = p_ca_cb;
4425
4426 /* mbedtls_ssl_conf_ca_chain() and mbedtls_ssl_conf_ca_cb()
4427 * cannot be used together. */
4428 conf->ca_chain = NULL;
4429 conf->ca_crl = NULL;
4430}
4431#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004432#endif /* MBEDTLS_X509_CRT_PARSE_C */
Paul Bakkereb2c6582012-09-27 19:15:01 +00004433
Manuel Pégourié-Gonnard1af6c852015-05-10 23:10:37 +02004434#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004435int mbedtls_ssl_set_hs_own_cert(mbedtls_ssl_context *ssl,
4436 mbedtls_x509_crt *own_cert,
4437 mbedtls_pk_context *pk_key)
Manuel Pégourié-Gonnard1af6c852015-05-10 23:10:37 +02004438{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004439 return ssl_append_key_cert(&ssl->handshake->sni_key_cert,
4440 own_cert, pk_key);
Manuel Pégourié-Gonnard1af6c852015-05-10 23:10:37 +02004441}
Manuel Pégourié-Gonnard22bfa4b2015-05-11 08:46:37 +02004442
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004443void mbedtls_ssl_set_hs_ca_chain(mbedtls_ssl_context *ssl,
4444 mbedtls_x509_crt *ca_chain,
4445 mbedtls_x509_crl *ca_crl)
Manuel Pégourié-Gonnard22bfa4b2015-05-11 08:46:37 +02004446{
4447 ssl->handshake->sni_ca_chain = ca_chain;
4448 ssl->handshake->sni_ca_crl = ca_crl;
4449}
Manuel Pégourié-Gonnardcdc26ae2015-06-19 12:16:31 +02004450
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004451void mbedtls_ssl_set_hs_authmode(mbedtls_ssl_context *ssl,
4452 int authmode)
Manuel Pégourié-Gonnardcdc26ae2015-06-19 12:16:31 +02004453{
4454 ssl->handshake->sni_authmode = authmode;
4455}
Manuel Pégourié-Gonnard1af6c852015-05-10 23:10:37 +02004456#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
4457
Hanno Becker8927c832019-04-03 12:52:50 +01004458#if defined(MBEDTLS_X509_CRT_PARSE_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004459void mbedtls_ssl_set_verify(mbedtls_ssl_context *ssl,
4460 int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
4461 void *p_vrfy)
Hanno Becker8927c832019-04-03 12:52:50 +01004462{
4463 ssl->f_vrfy = f_vrfy;
4464 ssl->p_vrfy = p_vrfy;
4465}
4466#endif
4467
Manuel Pégourié-Gonnardeef142d2015-09-16 10:05:04 +02004468#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
Manuel Pégourié-Gonnard7002f4a2015-09-15 12:43:43 +02004469/*
4470 * Set EC J-PAKE password for current handshake
4471 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004472int mbedtls_ssl_set_hs_ecjpake_password(mbedtls_ssl_context *ssl,
4473 const unsigned char *pw,
4474 size_t pw_len)
Manuel Pégourié-Gonnard7002f4a2015-09-15 12:43:43 +02004475{
4476 mbedtls_ecjpake_role role;
4477
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004478 if (ssl->handshake == NULL || ssl->conf == NULL) {
4479 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
4480 }
Manuel Pégourié-Gonnard7002f4a2015-09-15 12:43:43 +02004481
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004482 if (ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER) {
Manuel Pégourié-Gonnard7002f4a2015-09-15 12:43:43 +02004483 role = MBEDTLS_ECJPAKE_SERVER;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004484 } else {
Manuel Pégourié-Gonnard7002f4a2015-09-15 12:43:43 +02004485 role = MBEDTLS_ECJPAKE_CLIENT;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004486 }
Manuel Pégourié-Gonnard7002f4a2015-09-15 12:43:43 +02004487
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004488 return mbedtls_ecjpake_setup(&ssl->handshake->ecjpake_ctx,
4489 role,
4490 MBEDTLS_MD_SHA256,
4491 MBEDTLS_ECP_DP_SECP256R1,
4492 pw, pw_len);
Manuel Pégourié-Gonnard7002f4a2015-09-15 12:43:43 +02004493}
Manuel Pégourié-Gonnardeef142d2015-09-16 10:05:04 +02004494#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
Manuel Pégourié-Gonnard7002f4a2015-09-15 12:43:43 +02004495
Gilles Peskineeccd8882020-03-10 12:19:08 +01004496#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
Hanno Beckerd20a8ca2018-10-22 15:31:26 +01004497
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004498static void ssl_conf_remove_psk(mbedtls_ssl_config *conf)
Hanno Beckerd20a8ca2018-10-22 15:31:26 +01004499{
4500 /* Remove reference to existing PSK, if any. */
4501#if defined(MBEDTLS_USE_PSA_CRYPTO)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004502 if (!mbedtls_svc_key_id_is_null(conf->psk_opaque)) {
Hanno Beckerd20a8ca2018-10-22 15:31:26 +01004503 /* The maintenance of the PSK key slot is the
4504 * user's responsibility. */
Ronald Croncf56a0a2020-08-04 09:51:30 +02004505 conf->psk_opaque = MBEDTLS_SVC_KEY_ID_INIT;
Hanno Beckerd20a8ca2018-10-22 15:31:26 +01004506 }
Hanno Beckera63ac3f2018-11-05 12:47:16 +00004507 /* This and the following branch should never
Tom Cosgrove49f99bc2022-12-04 16:44:21 +00004508 * be taken simultaneously as we maintain the
Hanno Beckera63ac3f2018-11-05 12:47:16 +00004509 * invariant that raw and opaque PSKs are never
4510 * configured simultaneously. As a safeguard,
4511 * though, `else` is omitted here. */
Hanno Beckerd20a8ca2018-10-22 15:31:26 +01004512#endif /* MBEDTLS_USE_PSA_CRYPTO */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004513 if (conf->psk != NULL) {
4514 mbedtls_platform_zeroize(conf->psk, conf->psk_len);
Hanno Beckerd20a8ca2018-10-22 15:31:26 +01004515
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004516 mbedtls_free(conf->psk);
Hanno Beckerd20a8ca2018-10-22 15:31:26 +01004517 conf->psk = NULL;
4518 conf->psk_len = 0;
4519 }
4520
4521 /* Remove reference to PSK identity, if any. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004522 if (conf->psk_identity != NULL) {
4523 mbedtls_free(conf->psk_identity);
Hanno Beckerd20a8ca2018-10-22 15:31:26 +01004524 conf->psk_identity = NULL;
4525 conf->psk_identity_len = 0;
4526 }
4527}
4528
Hanno Becker7390c712018-11-15 13:33:04 +00004529/* This function assumes that PSK identity in the SSL config is unset.
4530 * It checks that the provided identity is well-formed and attempts
4531 * to make a copy of it in the SSL config.
4532 * On failure, the PSK identity in the config remains unset. */
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +02004533MBEDTLS_CHECK_RETURN_CRITICAL
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004534static int ssl_conf_set_psk_identity(mbedtls_ssl_config *conf,
4535 unsigned char const *psk_identity,
4536 size_t psk_identity_len)
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02004537{
Manuel Pégourié-Gonnardc6b5d832015-08-27 16:37:35 +02004538 /* Identity len will be encoded on two bytes */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004539 if (psk_identity == NULL ||
4540 (psk_identity_len >> 16) != 0 ||
4541 psk_identity_len > MBEDTLS_SSL_OUT_CONTENT_LEN) {
4542 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
Manuel Pégourié-Gonnardc6b5d832015-08-27 16:37:35 +02004543 }
4544
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004545 conf->psk_identity = mbedtls_calloc(1, psk_identity_len);
4546 if (conf->psk_identity == NULL) {
4547 return MBEDTLS_ERR_SSL_ALLOC_FAILED;
4548 }
Paul Bakker6db455e2013-09-18 17:29:31 +02004549
Manuel Pégourié-Gonnard120fdbd2015-05-07 17:07:50 +01004550 conf->psk_identity_len = psk_identity_len;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004551 memcpy(conf->psk_identity, psk_identity, conf->psk_identity_len);
Paul Bakker5ad403f2013-09-18 21:21:30 +02004552
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004553 return 0;
Paul Bakker6db455e2013-09-18 17:29:31 +02004554}
4555
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004556int mbedtls_ssl_conf_psk(mbedtls_ssl_config *conf,
4557 const unsigned char *psk, size_t psk_len,
4558 const unsigned char *psk_identity, size_t psk_identity_len)
Hanno Becker7390c712018-11-15 13:33:04 +00004559{
Janos Follath865b3eb2019-12-16 11:46:15 +00004560 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Hanno Becker7390c712018-11-15 13:33:04 +00004561 /* Remove opaque/raw PSK + PSK Identity */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004562 ssl_conf_remove_psk(conf);
Hanno Becker7390c712018-11-15 13:33:04 +00004563
4564 /* Check and set raw PSK */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004565 if (psk == NULL) {
4566 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
4567 }
4568 if (psk_len == 0) {
4569 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
4570 }
4571 if (psk_len > MBEDTLS_PSK_MAX_LEN) {
4572 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
4573 }
Piotr Nowicki9926eaf2019-11-20 14:54:36 +01004574
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004575 if ((conf->psk = mbedtls_calloc(1, psk_len)) == NULL) {
4576 return MBEDTLS_ERR_SSL_ALLOC_FAILED;
4577 }
Hanno Becker7390c712018-11-15 13:33:04 +00004578 conf->psk_len = psk_len;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004579 memcpy(conf->psk, psk, conf->psk_len);
Hanno Becker7390c712018-11-15 13:33:04 +00004580
4581 /* Check and set PSK Identity */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004582 ret = ssl_conf_set_psk_identity(conf, psk_identity, psk_identity_len);
4583 if (ret != 0) {
4584 ssl_conf_remove_psk(conf);
4585 }
Hanno Becker7390c712018-11-15 13:33:04 +00004586
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004587 return ret;
Hanno Becker7390c712018-11-15 13:33:04 +00004588}
4589
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004590static void ssl_remove_psk(mbedtls_ssl_context *ssl)
Hanno Beckerd20a8ca2018-10-22 15:31:26 +01004591{
4592#if defined(MBEDTLS_USE_PSA_CRYPTO)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004593 if (!mbedtls_svc_key_id_is_null(ssl->handshake->psk_opaque)) {
Ronald Croncf56a0a2020-08-04 09:51:30 +02004594 ssl->handshake->psk_opaque = MBEDTLS_SVC_KEY_ID_INIT;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004595 } else
Hanno Beckerd20a8ca2018-10-22 15:31:26 +01004596#endif /* MBEDTLS_USE_PSA_CRYPTO */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004597 if (ssl->handshake->psk != NULL) {
4598 mbedtls_platform_zeroize(ssl->handshake->psk,
4599 ssl->handshake->psk_len);
4600 mbedtls_free(ssl->handshake->psk);
Hanno Beckerd20a8ca2018-10-22 15:31:26 +01004601 ssl->handshake->psk_len = 0;
lhuang040a2dd6d2024-06-11 12:31:17 -07004602 ssl->handshake->psk = NULL;
Hanno Beckerd20a8ca2018-10-22 15:31:26 +01004603 }
4604}
4605
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004606int mbedtls_ssl_set_hs_psk(mbedtls_ssl_context *ssl,
4607 const unsigned char *psk, size_t psk_len)
Manuel Pégourié-Gonnard4b682962015-05-07 15:59:54 +01004608{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004609 if (psk == NULL || ssl->handshake == NULL) {
4610 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
4611 }
Manuel Pégourié-Gonnard4b682962015-05-07 15:59:54 +01004612
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004613 if (psk_len > MBEDTLS_PSK_MAX_LEN) {
4614 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
4615 }
Manuel Pégourié-Gonnard4b682962015-05-07 15:59:54 +01004616
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004617 ssl_remove_psk(ssl);
Manuel Pégourié-Gonnard4b682962015-05-07 15:59:54 +01004618
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004619 if ((ssl->handshake->psk = mbedtls_calloc(1, psk_len)) == NULL) {
4620 return MBEDTLS_ERR_SSL_ALLOC_FAILED;
4621 }
Manuel Pégourié-Gonnard4b682962015-05-07 15:59:54 +01004622
4623 ssl->handshake->psk_len = psk_len;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004624 memcpy(ssl->handshake->psk, psk, ssl->handshake->psk_len);
Manuel Pégourié-Gonnard4b682962015-05-07 15:59:54 +01004625
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004626 return 0;
Manuel Pégourié-Gonnard4b682962015-05-07 15:59:54 +01004627}
4628
Hanno Beckerd20a8ca2018-10-22 15:31:26 +01004629#if defined(MBEDTLS_USE_PSA_CRYPTO)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004630int mbedtls_ssl_conf_psk_opaque(mbedtls_ssl_config *conf,
4631 psa_key_id_t psk,
4632 const unsigned char *psk_identity,
4633 size_t psk_identity_len)
Hanno Beckerd20a8ca2018-10-22 15:31:26 +01004634{
Janos Follath865b3eb2019-12-16 11:46:15 +00004635 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Hanno Becker7390c712018-11-15 13:33:04 +00004636 /* Clear opaque/raw PSK + PSK Identity, if present. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004637 ssl_conf_remove_psk(conf);
Hanno Beckerd20a8ca2018-10-22 15:31:26 +01004638
Hanno Becker7390c712018-11-15 13:33:04 +00004639 /* Check and set opaque PSK */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004640 if (mbedtls_svc_key_id_is_null(psk)) {
4641 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
4642 }
Ronald Croncf56a0a2020-08-04 09:51:30 +02004643 conf->psk_opaque = psk;
Hanno Becker7390c712018-11-15 13:33:04 +00004644
4645 /* Check and set PSK Identity */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004646 ret = ssl_conf_set_psk_identity(conf, psk_identity,
4647 psk_identity_len);
4648 if (ret != 0) {
4649 ssl_conf_remove_psk(conf);
4650 }
Hanno Becker7390c712018-11-15 13:33:04 +00004651
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004652 return ret;
Hanno Beckerd20a8ca2018-10-22 15:31:26 +01004653}
4654
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004655int mbedtls_ssl_set_hs_psk_opaque(mbedtls_ssl_context *ssl,
4656 psa_key_id_t psk)
Hanno Beckerd20a8ca2018-10-22 15:31:26 +01004657{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004658 if ((mbedtls_svc_key_id_is_null(psk)) ||
4659 (ssl->handshake == NULL)) {
4660 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
4661 }
Hanno Beckerd20a8ca2018-10-22 15:31:26 +01004662
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004663 ssl_remove_psk(ssl);
Ronald Croncf56a0a2020-08-04 09:51:30 +02004664 ssl->handshake->psk_opaque = psk;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004665 return 0;
Hanno Beckerd20a8ca2018-10-22 15:31:26 +01004666}
4667#endif /* MBEDTLS_USE_PSA_CRYPTO */
4668
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004669void mbedtls_ssl_conf_psk_cb(mbedtls_ssl_config *conf,
4670 int (*f_psk)(void *, mbedtls_ssl_context *, const unsigned char *,
4671 size_t),
4672 void *p_psk)
Paul Bakker6db455e2013-09-18 17:29:31 +02004673{
Manuel Pégourié-Gonnardd36e33f2015-05-05 10:45:39 +02004674 conf->f_psk = f_psk;
4675 conf->p_psk = p_psk;
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02004676}
Gilles Peskineeccd8882020-03-10 12:19:08 +01004677#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
Paul Bakker43b7e352011-01-18 15:27:19 +00004678
Manuel Pégourié-Gonnardcf141ca2015-05-20 10:35:51 +02004679#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_SRV_C)
Hanno Becker470a8c42017-10-04 15:28:46 +01004680
4681#if !defined(MBEDTLS_DEPRECATED_REMOVED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004682int mbedtls_ssl_conf_dh_param(mbedtls_ssl_config *conf, const char *dhm_P, const char *dhm_G)
Paul Bakker5121ce52009-01-03 21:22:43 +00004683{
Janos Follath865b3eb2019-12-16 11:46:15 +00004684 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +00004685
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004686 if ((ret = mbedtls_mpi_read_string(&conf->dhm_P, 16, dhm_P)) != 0 ||
4687 (ret = mbedtls_mpi_read_string(&conf->dhm_G, 16, dhm_G)) != 0) {
4688 mbedtls_mpi_free(&conf->dhm_P);
4689 mbedtls_mpi_free(&conf->dhm_G);
4690 return ret;
Manuel Pégourié-Gonnard1028b742015-05-06 17:33:07 +01004691 }
Paul Bakker5121ce52009-01-03 21:22:43 +00004692
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004693 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +00004694}
Hanno Becker470a8c42017-10-04 15:28:46 +01004695#endif /* MBEDTLS_DEPRECATED_REMOVED */
Paul Bakker5121ce52009-01-03 21:22:43 +00004696
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004697int mbedtls_ssl_conf_dh_param_bin(mbedtls_ssl_config *conf,
4698 const unsigned char *dhm_P, size_t P_len,
4699 const unsigned char *dhm_G, size_t G_len)
Hanno Beckera90658f2017-10-04 15:29:08 +01004700{
Janos Follath865b3eb2019-12-16 11:46:15 +00004701 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Hanno Beckera90658f2017-10-04 15:29:08 +01004702
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004703 mbedtls_mpi_free(&conf->dhm_P);
4704 mbedtls_mpi_free(&conf->dhm_G);
Glenn Straussde081ce2021-12-20 01:43:17 -05004705
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004706 if ((ret = mbedtls_mpi_read_binary(&conf->dhm_P, dhm_P, P_len)) != 0 ||
4707 (ret = mbedtls_mpi_read_binary(&conf->dhm_G, dhm_G, G_len)) != 0) {
4708 mbedtls_mpi_free(&conf->dhm_P);
4709 mbedtls_mpi_free(&conf->dhm_G);
4710 return ret;
Hanno Beckera90658f2017-10-04 15:29:08 +01004711 }
4712
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004713 return 0;
Hanno Beckera90658f2017-10-04 15:29:08 +01004714}
Paul Bakker5121ce52009-01-03 21:22:43 +00004715
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004716int mbedtls_ssl_conf_dh_param_ctx(mbedtls_ssl_config *conf, mbedtls_dhm_context *dhm_ctx)
Paul Bakker1b57b062011-01-06 15:48:19 +00004717{
Janos Follath865b3eb2019-12-16 11:46:15 +00004718 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker1b57b062011-01-06 15:48:19 +00004719
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004720 mbedtls_mpi_free(&conf->dhm_P);
4721 mbedtls_mpi_free(&conf->dhm_G);
Glenn Straussde081ce2021-12-20 01:43:17 -05004722
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004723 if ((ret = mbedtls_mpi_copy(&conf->dhm_P, &dhm_ctx->P)) != 0 ||
4724 (ret = mbedtls_mpi_copy(&conf->dhm_G, &dhm_ctx->G)) != 0) {
4725 mbedtls_mpi_free(&conf->dhm_P);
4726 mbedtls_mpi_free(&conf->dhm_G);
4727 return ret;
Manuel Pégourié-Gonnard1028b742015-05-06 17:33:07 +01004728 }
Paul Bakker1b57b062011-01-06 15:48:19 +00004729
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004730 return 0;
Paul Bakker1b57b062011-01-06 15:48:19 +00004731}
Manuel Pégourié-Gonnardcf141ca2015-05-20 10:35:51 +02004732#endif /* MBEDTLS_DHM_C && MBEDTLS_SSL_SRV_C */
Paul Bakker1b57b062011-01-06 15:48:19 +00004733
Manuel Pégourié-Gonnardbd990d62015-06-11 14:49:42 +02004734#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_CLI_C)
4735/*
4736 * Set the minimum length for Diffie-Hellman parameters
4737 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004738void mbedtls_ssl_conf_dhm_min_bitlen(mbedtls_ssl_config *conf,
4739 unsigned int bitlen)
Manuel Pégourié-Gonnardbd990d62015-06-11 14:49:42 +02004740{
4741 conf->dhm_min_bitlen = bitlen;
4742}
4743#endif /* MBEDTLS_DHM_C && MBEDTLS_SSL_CLI_C */
4744
Gilles Peskineeccd8882020-03-10 12:19:08 +01004745#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
Manuel Pégourié-Gonnard36a8b572015-06-17 12:43:26 +02004746/*
4747 * Set allowed/preferred hashes for handshake signatures
4748 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004749void mbedtls_ssl_conf_sig_hashes(mbedtls_ssl_config *conf,
4750 const int *hashes)
Manuel Pégourié-Gonnard36a8b572015-06-17 12:43:26 +02004751{
4752 conf->sig_hashes = hashes;
4753}
Gilles Peskineeccd8882020-03-10 12:19:08 +01004754#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
Manuel Pégourié-Gonnard36a8b572015-06-17 12:43:26 +02004755
Manuel Pégourié-Gonnardb541da62015-06-17 11:43:30 +02004756#if defined(MBEDTLS_ECP_C)
Manuel Pégourié-Gonnard7f38ed02014-02-04 15:52:33 +01004757/*
4758 * Set the allowed elliptic curves
4759 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004760void mbedtls_ssl_conf_curves(mbedtls_ssl_config *conf,
4761 const mbedtls_ecp_group_id *curve_list)
Manuel Pégourié-Gonnard7f38ed02014-02-04 15:52:33 +01004762{
Manuel Pégourié-Gonnardd36e33f2015-05-05 10:45:39 +02004763 conf->curve_list = curve_list;
Manuel Pégourié-Gonnard7f38ed02014-02-04 15:52:33 +01004764}
Hanno Becker947194e2017-04-07 13:25:49 +01004765#endif /* MBEDTLS_ECP_C */
Manuel Pégourié-Gonnard7f38ed02014-02-04 15:52:33 +01004766
Manuel Pégourié-Gonnardbc2b7712015-05-06 11:14:19 +01004767#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004768void mbedtls_ssl_conf_sni(mbedtls_ssl_config *conf,
4769 int (*f_sni)(void *, mbedtls_ssl_context *,
4770 const unsigned char *, size_t),
4771 void *p_sni)
Paul Bakker5701cdc2012-09-27 21:49:42 +00004772{
Manuel Pégourié-Gonnardd36e33f2015-05-05 10:45:39 +02004773 conf->f_sni = f_sni;
4774 conf->p_sni = p_sni;
Paul Bakker5701cdc2012-09-27 21:49:42 +00004775}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004776#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
Paul Bakker5701cdc2012-09-27 21:49:42 +00004777
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004778#if defined(MBEDTLS_SSL_ALPN)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004779int mbedtls_ssl_conf_alpn_protocols(mbedtls_ssl_config *conf, const char **protos)
Manuel Pégourié-Gonnard7e250d42014-04-04 16:08:41 +02004780{
Manuel Pégourié-Gonnard0b874dc2014-04-07 10:57:45 +02004781 size_t cur_len, tot_len;
4782 const char **p;
4783
4784 /*
Brian J Murray1903fb32016-11-06 04:45:15 -08004785 * RFC 7301 3.1: "Empty strings MUST NOT be included and byte strings
4786 * MUST NOT be truncated."
4787 * We check lengths now rather than later.
Manuel Pégourié-Gonnard0b874dc2014-04-07 10:57:45 +02004788 */
4789 tot_len = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004790 for (p = protos; *p != NULL; p++) {
4791 cur_len = strlen(*p);
Manuel Pégourié-Gonnard0b874dc2014-04-07 10:57:45 +02004792 tot_len += cur_len;
4793
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004794 if ((cur_len == 0) ||
4795 (cur_len > MBEDTLS_SSL_MAX_ALPN_NAME_LEN) ||
4796 (tot_len > MBEDTLS_SSL_MAX_ALPN_LIST_LEN)) {
4797 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
4798 }
Manuel Pégourié-Gonnard0b874dc2014-04-07 10:57:45 +02004799 }
4800
Manuel Pégourié-Gonnardd36e33f2015-05-05 10:45:39 +02004801 conf->alpn_list = protos;
Manuel Pégourié-Gonnard0b874dc2014-04-07 10:57:45 +02004802
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004803 return 0;
Manuel Pégourié-Gonnard7e250d42014-04-04 16:08:41 +02004804}
4805
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004806const char *mbedtls_ssl_get_alpn_protocol(const mbedtls_ssl_context *ssl)
Manuel Pégourié-Gonnard7e250d42014-04-04 16:08:41 +02004807{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004808 return ssl->alpn_chosen;
Manuel Pégourié-Gonnard7e250d42014-04-04 16:08:41 +02004809}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004810#endif /* MBEDTLS_SSL_ALPN */
Manuel Pégourié-Gonnard7e250d42014-04-04 16:08:41 +02004811
Johan Pascalb62bb512015-12-03 21:56:45 +01004812#if defined(MBEDTLS_SSL_DTLS_SRTP)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004813void mbedtls_ssl_conf_srtp_mki_value_supported(mbedtls_ssl_config *conf,
4814 int support_mki_value)
Ron Eldor591f1622018-01-22 12:30:04 +02004815{
4816 conf->dtls_srtp_mki_support = support_mki_value;
4817}
4818
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004819int mbedtls_ssl_dtls_srtp_set_mki_value(mbedtls_ssl_context *ssl,
4820 unsigned char *mki_value,
4821 uint16_t mki_len)
Ron Eldor591f1622018-01-22 12:30:04 +02004822{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004823 if (mki_len > MBEDTLS_TLS_SRTP_MAX_MKI_LENGTH) {
4824 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
Ron Eldora9788042018-12-05 11:04:31 +02004825 }
Ron Eldor591f1622018-01-22 12:30:04 +02004826
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004827 if (ssl->conf->dtls_srtp_mki_support == MBEDTLS_SSL_DTLS_SRTP_MKI_UNSUPPORTED) {
4828 return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
Ron Eldora9788042018-12-05 11:04:31 +02004829 }
Ron Eldor591f1622018-01-22 12:30:04 +02004830
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004831 memcpy(ssl->dtls_srtp_info.mki_value, mki_value, mki_len);
Ron Eldor591f1622018-01-22 12:30:04 +02004832 ssl->dtls_srtp_info.mki_len = mki_len;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004833 return 0;
Ron Eldor591f1622018-01-22 12:30:04 +02004834}
4835
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004836int mbedtls_ssl_conf_dtls_srtp_protection_profiles(mbedtls_ssl_config *conf,
4837 const mbedtls_ssl_srtp_profile *profiles)
Johan Pascalb62bb512015-12-03 21:56:45 +01004838{
Johan Pascal253d0262020-09-22 13:04:45 +02004839 const mbedtls_ssl_srtp_profile *p;
4840 size_t list_size = 0;
Johan Pascalb62bb512015-12-03 21:56:45 +01004841
Johan Pascal253d0262020-09-22 13:04:45 +02004842 /* check the profiles list: all entry must be valid,
4843 * its size cannot be more than the total number of supported profiles, currently 4 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004844 for (p = profiles; *p != MBEDTLS_TLS_SRTP_UNSET &&
4845 list_size <= MBEDTLS_TLS_SRTP_MAX_PROFILE_LIST_LENGTH;
4846 p++) {
4847 if (mbedtls_ssl_check_srtp_profile_value(*p) != MBEDTLS_TLS_SRTP_UNSET) {
Johan Pascal76fdf1d2020-10-22 23:31:00 +02004848 list_size++;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004849 } else {
Johan Pascal76fdf1d2020-10-22 23:31:00 +02004850 /* unsupported value, stop parsing and set the size to an error value */
4851 list_size = MBEDTLS_TLS_SRTP_MAX_PROFILE_LIST_LENGTH + 1;
Johan Pascalb62bb512015-12-03 21:56:45 +01004852 }
4853 }
4854
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004855 if (list_size > MBEDTLS_TLS_SRTP_MAX_PROFILE_LIST_LENGTH) {
4856 conf->dtls_srtp_profile_list = NULL;
4857 conf->dtls_srtp_profile_list_len = 0;
4858 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
Johan Pascal253d0262020-09-22 13:04:45 +02004859 }
4860
Johan Pascal9bc97ca2020-09-21 23:44:45 +02004861 conf->dtls_srtp_profile_list = profiles;
Johan Pascal253d0262020-09-22 13:04:45 +02004862 conf->dtls_srtp_profile_list_len = list_size;
Johan Pascalb62bb512015-12-03 21:56:45 +01004863
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004864 return 0;
Johan Pascalb62bb512015-12-03 21:56:45 +01004865}
4866
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004867void mbedtls_ssl_get_dtls_srtp_negotiation_result(const mbedtls_ssl_context *ssl,
4868 mbedtls_dtls_srtp_info *dtls_srtp_info)
Johan Pascalb62bb512015-12-03 21:56:45 +01004869{
Johan Pascal2258a4f2020-10-28 13:53:09 +01004870 dtls_srtp_info->chosen_dtls_srtp_profile = ssl->dtls_srtp_info.chosen_dtls_srtp_profile;
4871 /* do not copy the mki value if there is no chosen profile */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004872 if (dtls_srtp_info->chosen_dtls_srtp_profile == MBEDTLS_TLS_SRTP_UNSET) {
Johan Pascal2258a4f2020-10-28 13:53:09 +01004873 dtls_srtp_info->mki_len = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004874 } else {
Johan Pascal2258a4f2020-10-28 13:53:09 +01004875 dtls_srtp_info->mki_len = ssl->dtls_srtp_info.mki_len;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004876 memcpy(dtls_srtp_info->mki_value, ssl->dtls_srtp_info.mki_value,
4877 ssl->dtls_srtp_info.mki_len);
Johan Pascal2258a4f2020-10-28 13:53:09 +01004878 }
Johan Pascalb62bb512015-12-03 21:56:45 +01004879}
Johan Pascalb62bb512015-12-03 21:56:45 +01004880#endif /* MBEDTLS_SSL_DTLS_SRTP */
4881
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004882void mbedtls_ssl_conf_max_version(mbedtls_ssl_config *conf, int major, int minor)
Paul Bakker490ecc82011-10-06 13:04:09 +00004883{
Manuel Pégourié-Gonnardd36e33f2015-05-05 10:45:39 +02004884 conf->max_major_ver = major;
4885 conf->max_minor_ver = minor;
Paul Bakker490ecc82011-10-06 13:04:09 +00004886}
4887
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004888void mbedtls_ssl_conf_min_version(mbedtls_ssl_config *conf, int major, int minor)
Paul Bakker1d29fb52012-09-28 13:28:45 +00004889{
Manuel Pégourié-Gonnardd36e33f2015-05-05 10:45:39 +02004890 conf->min_major_ver = major;
4891 conf->min_minor_ver = minor;
Paul Bakker1d29fb52012-09-28 13:28:45 +00004892}
4893
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004894#if defined(MBEDTLS_SSL_FALLBACK_SCSV) && defined(MBEDTLS_SSL_CLI_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004895void mbedtls_ssl_conf_fallback(mbedtls_ssl_config *conf, char fallback)
Manuel Pégourié-Gonnard1cbd39d2014-10-20 13:34:59 +02004896{
Manuel Pégourié-Gonnard684b0592015-05-06 09:27:31 +01004897 conf->fallback = fallback;
Manuel Pégourié-Gonnard1cbd39d2014-10-20 13:34:59 +02004898}
4899#endif
4900
Janos Follath088ce432017-04-10 12:42:31 +01004901#if defined(MBEDTLS_SSL_SRV_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004902void mbedtls_ssl_conf_cert_req_ca_list(mbedtls_ssl_config *conf,
4903 char cert_req_ca_list)
Janos Follath088ce432017-04-10 12:42:31 +01004904{
4905 conf->cert_req_ca_list = cert_req_ca_list;
4906}
4907#endif
4908
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004909#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004910void mbedtls_ssl_conf_encrypt_then_mac(mbedtls_ssl_config *conf, char etm)
Manuel Pégourié-Gonnard699cafa2014-10-27 13:57:03 +01004911{
Manuel Pégourié-Gonnardd36e33f2015-05-05 10:45:39 +02004912 conf->encrypt_then_mac = etm;
Manuel Pégourié-Gonnard699cafa2014-10-27 13:57:03 +01004913}
4914#endif
4915
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004916#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004917void mbedtls_ssl_conf_extended_master_secret(mbedtls_ssl_config *conf, char ems)
Manuel Pégourié-Gonnard367381f2014-10-20 18:40:56 +02004918{
Manuel Pégourié-Gonnardd36e33f2015-05-05 10:45:39 +02004919 conf->extended_ms = ems;
Manuel Pégourié-Gonnard367381f2014-10-20 18:40:56 +02004920}
4921#endif
4922
Manuel Pégourié-Gonnard66dc5552015-05-14 12:28:21 +02004923#if defined(MBEDTLS_ARC4_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004924void mbedtls_ssl_conf_arc4_support(mbedtls_ssl_config *conf, char arc4)
Manuel Pégourié-Gonnardbd47a582015-01-12 13:43:29 +01004925{
Manuel Pégourié-Gonnardd36e33f2015-05-05 10:45:39 +02004926 conf->arc4_disabled = arc4;
Manuel Pégourié-Gonnardbd47a582015-01-12 13:43:29 +01004927}
Manuel Pégourié-Gonnard66dc5552015-05-14 12:28:21 +02004928#endif
Manuel Pégourié-Gonnardbd47a582015-01-12 13:43:29 +01004929
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004930#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004931int mbedtls_ssl_conf_max_frag_len(mbedtls_ssl_config *conf, unsigned char mfl_code)
Manuel Pégourié-Gonnard8b464592013-07-16 12:45:26 +02004932{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004933 if (mfl_code >= MBEDTLS_SSL_MAX_FRAG_LEN_INVALID ||
4934 ssl_mfl_code_to_length(mfl_code) > MBEDTLS_TLS_EXT_ADV_CONTENT_LEN) {
4935 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
Manuel Pégourié-Gonnard8b464592013-07-16 12:45:26 +02004936 }
4937
Manuel Pégourié-Gonnard6bf89d62015-05-05 17:01:57 +01004938 conf->mfl_code = mfl_code;
Manuel Pégourié-Gonnard8b464592013-07-16 12:45:26 +02004939
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004940 return 0;
Manuel Pégourié-Gonnard8b464592013-07-16 12:45:26 +02004941}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004942#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
Manuel Pégourié-Gonnard8b464592013-07-16 12:45:26 +02004943
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004944#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004945void mbedtls_ssl_conf_truncated_hmac(mbedtls_ssl_config *conf, int truncate)
Manuel Pégourié-Gonnarde980a992013-07-19 11:08:52 +02004946{
Manuel Pégourié-Gonnardd36e33f2015-05-05 10:45:39 +02004947 conf->trunc_hmac = truncate;
Manuel Pégourié-Gonnarde980a992013-07-19 11:08:52 +02004948}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004949#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
Manuel Pégourié-Gonnarde980a992013-07-19 11:08:52 +02004950
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004951#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004952void mbedtls_ssl_conf_cbc_record_splitting(mbedtls_ssl_config *conf, char split)
Manuel Pégourié-Gonnardcfa477e2015-01-07 14:50:54 +01004953{
Manuel Pégourié-Gonnard17eab2b2015-05-05 16:34:53 +01004954 conf->cbc_record_splitting = split;
Manuel Pégourié-Gonnardcfa477e2015-01-07 14:50:54 +01004955}
4956#endif
4957
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004958void mbedtls_ssl_conf_legacy_renegotiation(mbedtls_ssl_config *conf, int allow_legacy)
Paul Bakker48916f92012-09-16 19:57:18 +00004959{
Manuel Pégourié-Gonnardd36e33f2015-05-05 10:45:39 +02004960 conf->allow_legacy_renegotiation = allow_legacy;
Paul Bakker48916f92012-09-16 19:57:18 +00004961}
4962
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004963#if defined(MBEDTLS_SSL_RENEGOTIATION)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004964void mbedtls_ssl_conf_renegotiation(mbedtls_ssl_config *conf, int renegotiation)
Manuel Pégourié-Gonnard615e6772014-11-03 08:23:14 +01004965{
Manuel Pégourié-Gonnardd36e33f2015-05-05 10:45:39 +02004966 conf->disable_renegotiation = renegotiation;
Manuel Pégourié-Gonnard615e6772014-11-03 08:23:14 +01004967}
4968
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004969void mbedtls_ssl_conf_renegotiation_enforced(mbedtls_ssl_config *conf, int max_records)
Manuel Pégourié-Gonnarda9964db2014-07-03 19:29:16 +02004970{
Manuel Pégourié-Gonnardd36e33f2015-05-05 10:45:39 +02004971 conf->renego_max_records = max_records;
Manuel Pégourié-Gonnarda9964db2014-07-03 19:29:16 +02004972}
4973
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004974void mbedtls_ssl_conf_renegotiation_period(mbedtls_ssl_config *conf,
4975 const unsigned char period[8])
Manuel Pégourié-Gonnard837f0fe2014-11-05 13:58:53 +01004976{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004977 memcpy(conf->renego_period, period, 8);
Manuel Pégourié-Gonnard837f0fe2014-11-05 13:58:53 +01004978}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004979#endif /* MBEDTLS_SSL_RENEGOTIATION */
Paul Bakker5121ce52009-01-03 21:22:43 +00004980
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004981#if defined(MBEDTLS_SSL_SESSION_TICKETS)
Manuel Pégourié-Gonnardb596abf2015-05-20 10:45:29 +02004982#if defined(MBEDTLS_SSL_CLI_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004983void mbedtls_ssl_conf_session_tickets(mbedtls_ssl_config *conf, int use_tickets)
Manuel Pégourié-Gonnardaa0d4d12013-08-03 13:02:31 +02004984{
Manuel Pégourié-Gonnard2b494452015-05-06 10:05:11 +01004985 conf->session_tickets = use_tickets;
Manuel Pégourié-Gonnardaa0d4d12013-08-03 13:02:31 +02004986}
Manuel Pégourié-Gonnardb596abf2015-05-20 10:45:29 +02004987#endif
Paul Bakker606b4ba2013-08-14 16:52:14 +02004988
Manuel Pégourié-Gonnardb596abf2015-05-20 10:45:29 +02004989#if defined(MBEDTLS_SSL_SRV_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004990void mbedtls_ssl_conf_session_tickets_cb(mbedtls_ssl_config *conf,
4991 mbedtls_ssl_ticket_write_t *f_ticket_write,
4992 mbedtls_ssl_ticket_parse_t *f_ticket_parse,
4993 void *p_ticket)
Paul Bakker606b4ba2013-08-14 16:52:14 +02004994{
Manuel Pégourié-Gonnardd59675d2015-05-19 15:28:00 +02004995 conf->f_ticket_write = f_ticket_write;
4996 conf->f_ticket_parse = f_ticket_parse;
4997 conf->p_ticket = p_ticket;
Paul Bakker606b4ba2013-08-14 16:52:14 +02004998}
Manuel Pégourié-Gonnardb596abf2015-05-20 10:45:29 +02004999#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005000#endif /* MBEDTLS_SSL_SESSION_TICKETS */
Manuel Pégourié-Gonnardaa0d4d12013-08-03 13:02:31 +02005001
Robert Cragie4feb7ae2015-10-02 13:33:37 +01005002#if defined(MBEDTLS_SSL_EXPORT_KEYS)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005003void mbedtls_ssl_conf_export_keys_cb(mbedtls_ssl_config *conf,
5004 mbedtls_ssl_export_keys_t *f_export_keys,
5005 void *p_export_keys)
Robert Cragie4feb7ae2015-10-02 13:33:37 +01005006{
5007 conf->f_export_keys = f_export_keys;
5008 conf->p_export_keys = p_export_keys;
5009}
Ron Eldorf5cc10d2019-05-07 18:33:40 +03005010
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005011void mbedtls_ssl_conf_export_keys_ext_cb(mbedtls_ssl_config *conf,
5012 mbedtls_ssl_export_keys_ext_t *f_export_keys_ext,
5013 void *p_export_keys)
Ron Eldorf5cc10d2019-05-07 18:33:40 +03005014{
5015 conf->f_export_keys_ext = f_export_keys_ext;
5016 conf->p_export_keys = p_export_keys;
5017}
Robert Cragie4feb7ae2015-10-02 13:33:37 +01005018#endif
5019
Gilles Peskineb74a1c72018-04-24 13:09:22 +02005020#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
Gilles Peskine8bf79f62018-01-05 21:11:53 +01005021void mbedtls_ssl_conf_async_private_cb(
5022 mbedtls_ssl_config *conf,
5023 mbedtls_ssl_async_sign_t *f_async_sign,
5024 mbedtls_ssl_async_decrypt_t *f_async_decrypt,
5025 mbedtls_ssl_async_resume_t *f_async_resume,
5026 mbedtls_ssl_async_cancel_t *f_async_cancel,
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005027 void *async_config_data)
Gilles Peskine8bf79f62018-01-05 21:11:53 +01005028{
5029 conf->f_async_sign_start = f_async_sign;
5030 conf->f_async_decrypt_start = f_async_decrypt;
5031 conf->f_async_resume = f_async_resume;
5032 conf->f_async_cancel = f_async_cancel;
Gilles Peskinedf13d5c2018-04-25 20:39:48 +02005033 conf->p_async_config_data = async_config_data;
5034}
5035
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005036void *mbedtls_ssl_conf_get_async_config_data(const mbedtls_ssl_config *conf)
Gilles Peskine8f97af72018-04-26 11:46:10 +02005037{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005038 return conf->p_async_config_data;
Gilles Peskine8f97af72018-04-26 11:46:10 +02005039}
5040
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005041void *mbedtls_ssl_get_async_operation_data(const mbedtls_ssl_context *ssl)
Gilles Peskinedf13d5c2018-04-25 20:39:48 +02005042{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005043 if (ssl->handshake == NULL) {
5044 return NULL;
5045 } else {
5046 return ssl->handshake->user_async_ctx;
5047 }
Gilles Peskinedf13d5c2018-04-25 20:39:48 +02005048}
5049
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005050void mbedtls_ssl_set_async_operation_data(mbedtls_ssl_context *ssl,
5051 void *ctx)
Gilles Peskinedf13d5c2018-04-25 20:39:48 +02005052{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005053 if (ssl->handshake != NULL) {
Gilles Peskinedf13d5c2018-04-25 20:39:48 +02005054 ssl->handshake->user_async_ctx = ctx;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005055 }
Gilles Peskine8bf79f62018-01-05 21:11:53 +01005056}
Gilles Peskineb74a1c72018-04-24 13:09:22 +02005057#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
Gilles Peskine8bf79f62018-01-05 21:11:53 +01005058
Paul Bakker5121ce52009-01-03 21:22:43 +00005059/*
5060 * SSL get accessors
5061 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005062uint32_t mbedtls_ssl_get_verify_result(const mbedtls_ssl_context *ssl)
Paul Bakker5121ce52009-01-03 21:22:43 +00005063{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005064 if (ssl->session != NULL) {
5065 return ssl->session->verify_result;
5066 }
Manuel Pégourié-Gonnarde89163c2015-01-23 14:30:57 +00005067
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005068 if (ssl->session_negotiate != NULL) {
5069 return ssl->session_negotiate->verify_result;
5070 }
Manuel Pégourié-Gonnarde89163c2015-01-23 14:30:57 +00005071
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005072 return 0xFFFFFFFF;
Paul Bakker5121ce52009-01-03 21:22:43 +00005073}
5074
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005075const char *mbedtls_ssl_get_ciphersuite(const mbedtls_ssl_context *ssl)
Paul Bakker72f62662011-01-16 21:27:44 +00005076{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005077 if (ssl == NULL || ssl->session == NULL) {
5078 return NULL;
5079 }
Paul Bakker926c8e42013-03-06 10:23:34 +01005080
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005081 return mbedtls_ssl_get_ciphersuite_name(ssl->session->ciphersuite);
Paul Bakker72f62662011-01-16 21:27:44 +00005082}
5083
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005084const char *mbedtls_ssl_get_version(const mbedtls_ssl_context *ssl)
Paul Bakker43ca69c2011-01-15 17:35:19 +00005085{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005086#if defined(MBEDTLS_SSL_PROTO_DTLS)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005087 if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
5088 switch (ssl->minor_ver) {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005089 case MBEDTLS_SSL_MINOR_VERSION_2:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005090 return "DTLSv1.0";
Manuel Pégourié-Gonnardb21ca2a2014-02-10 13:43:33 +01005091
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005092 case MBEDTLS_SSL_MINOR_VERSION_3:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005093 return "DTLSv1.2";
Manuel Pégourié-Gonnardb21ca2a2014-02-10 13:43:33 +01005094
5095 default:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005096 return "unknown (DTLS)";
Manuel Pégourié-Gonnardb21ca2a2014-02-10 13:43:33 +01005097 }
5098 }
5099#endif
5100
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005101 switch (ssl->minor_ver) {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005102 case MBEDTLS_SSL_MINOR_VERSION_0:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005103 return "SSLv3.0";
Paul Bakker43ca69c2011-01-15 17:35:19 +00005104
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005105 case MBEDTLS_SSL_MINOR_VERSION_1:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005106 return "TLSv1.0";
Paul Bakker43ca69c2011-01-15 17:35:19 +00005107
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005108 case MBEDTLS_SSL_MINOR_VERSION_2:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005109 return "TLSv1.1";
Paul Bakker43ca69c2011-01-15 17:35:19 +00005110
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005111 case MBEDTLS_SSL_MINOR_VERSION_3:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005112 return "TLSv1.2";
Paul Bakker1ef83d62012-04-11 12:09:53 +00005113
Paul Bakker43ca69c2011-01-15 17:35:19 +00005114 default:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005115 return "unknown";
Paul Bakker43ca69c2011-01-15 17:35:19 +00005116 }
Paul Bakker43ca69c2011-01-15 17:35:19 +00005117}
5118
Manuel Pégourié-Gonnarda2cda6b2015-08-31 18:30:52 +02005119#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005120size_t mbedtls_ssl_get_input_max_frag_len(const mbedtls_ssl_context *ssl)
Andrzej Kurek90c6e842020-04-03 05:25:29 -04005121{
5122 size_t max_len = MBEDTLS_SSL_MAX_CONTENT_LEN;
5123 size_t read_mfl;
5124
5125 /* Use the configured MFL for the client if we're past SERVER_HELLO_DONE */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005126 if (ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT &&
5127 ssl->state >= MBEDTLS_SSL_SERVER_HELLO_DONE) {
5128 return ssl_mfl_code_to_length(ssl->conf->mfl_code);
Andrzej Kurek90c6e842020-04-03 05:25:29 -04005129 }
5130
5131 /* Check if a smaller max length was negotiated */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005132 if (ssl->session_out != NULL) {
5133 read_mfl = ssl_mfl_code_to_length(ssl->session_out->mfl_code);
5134 if (read_mfl < max_len) {
Andrzej Kurek90c6e842020-04-03 05:25:29 -04005135 max_len = read_mfl;
5136 }
5137 }
5138
5139 // During a handshake, use the value being negotiated
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005140 if (ssl->session_negotiate != NULL) {
5141 read_mfl = ssl_mfl_code_to_length(ssl->session_negotiate->mfl_code);
5142 if (read_mfl < max_len) {
Andrzej Kurek90c6e842020-04-03 05:25:29 -04005143 max_len = read_mfl;
5144 }
5145 }
5146
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005147 return max_len;
Andrzej Kurek90c6e842020-04-03 05:25:29 -04005148}
5149
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005150size_t mbedtls_ssl_get_output_max_frag_len(const mbedtls_ssl_context *ssl)
Manuel Pégourié-Gonnarda2cda6b2015-08-31 18:30:52 +02005151{
5152 size_t max_len;
5153
5154 /*
5155 * Assume mfl_code is correct since it was checked when set
5156 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005157 max_len = ssl_mfl_code_to_length(ssl->conf->mfl_code);
Manuel Pégourié-Gonnarda2cda6b2015-08-31 18:30:52 +02005158
Manuel Pégourié-Gonnard2cb17e22017-09-19 13:00:47 +02005159 /* Check if a smaller max length was negotiated */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005160 if (ssl->session_out != NULL &&
5161 ssl_mfl_code_to_length(ssl->session_out->mfl_code) < max_len) {
5162 max_len = ssl_mfl_code_to_length(ssl->session_out->mfl_code);
Manuel Pégourié-Gonnarda2cda6b2015-08-31 18:30:52 +02005163 }
5164
Manuel Pégourié-Gonnard2cb17e22017-09-19 13:00:47 +02005165 /* During a handshake, use the value being negotiated */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005166 if (ssl->session_negotiate != NULL &&
5167 ssl_mfl_code_to_length(ssl->session_negotiate->mfl_code) < max_len) {
5168 max_len = ssl_mfl_code_to_length(ssl->session_negotiate->mfl_code);
Manuel Pégourié-Gonnard2cb17e22017-09-19 13:00:47 +02005169 }
5170
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005171 return max_len;
Manuel Pégourié-Gonnarda2cda6b2015-08-31 18:30:52 +02005172}
Andrzej Kurek90c6e842020-04-03 05:25:29 -04005173
5174#if !defined(MBEDTLS_DEPRECATED_REMOVED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005175size_t mbedtls_ssl_get_max_frag_len(const mbedtls_ssl_context *ssl)
Andrzej Kurek90c6e842020-04-03 05:25:29 -04005176{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005177 return mbedtls_ssl_get_output_max_frag_len(ssl);
Andrzej Kurek90c6e842020-04-03 05:25:29 -04005178}
5179#endif /* !MBEDTLS_DEPRECATED_REMOVED */
Manuel Pégourié-Gonnarda2cda6b2015-08-31 18:30:52 +02005180#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
5181
Manuel Pégourié-Gonnardb8eec192018-08-20 09:34:02 +02005182#if defined(MBEDTLS_SSL_PROTO_DTLS)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005183size_t mbedtls_ssl_get_current_mtu(const mbedtls_ssl_context *ssl)
Manuel Pégourié-Gonnardb8eec192018-08-20 09:34:02 +02005184{
Andrzej Kurekef43ce62018-10-09 08:24:12 -04005185 /* Return unlimited mtu for client hello messages to avoid fragmentation. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005186 if (ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT &&
5187 (ssl->state == MBEDTLS_SSL_CLIENT_HELLO ||
5188 ssl->state == MBEDTLS_SSL_SERVER_HELLO)) {
5189 return 0;
5190 }
Andrzej Kurekef43ce62018-10-09 08:24:12 -04005191
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005192 if (ssl->handshake == NULL || ssl->handshake->mtu == 0) {
5193 return ssl->mtu;
5194 }
Manuel Pégourié-Gonnardb8eec192018-08-20 09:34:02 +02005195
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005196 if (ssl->mtu == 0) {
5197 return ssl->handshake->mtu;
5198 }
Manuel Pégourié-Gonnardb8eec192018-08-20 09:34:02 +02005199
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005200 return ssl->mtu < ssl->handshake->mtu ?
5201 ssl->mtu : ssl->handshake->mtu;
Manuel Pégourié-Gonnardb8eec192018-08-20 09:34:02 +02005202}
5203#endif /* MBEDTLS_SSL_PROTO_DTLS */
5204
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005205int mbedtls_ssl_get_max_out_record_payload(const mbedtls_ssl_context *ssl)
Manuel Pégourié-Gonnard9468ff12017-09-21 13:49:50 +02005206{
5207 size_t max_len = MBEDTLS_SSL_OUT_CONTENT_LEN;
5208
Manuel Pégourié-Gonnard000281e2018-08-21 11:20:58 +02005209#if !defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) && \
5210 !defined(MBEDTLS_SSL_PROTO_DTLS)
5211 (void) ssl;
5212#endif
5213
Manuel Pégourié-Gonnard9468ff12017-09-21 13:49:50 +02005214#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005215 const size_t mfl = mbedtls_ssl_get_output_max_frag_len(ssl);
Manuel Pégourié-Gonnard9468ff12017-09-21 13:49:50 +02005216
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005217 if (max_len > mfl) {
Manuel Pégourié-Gonnard9468ff12017-09-21 13:49:50 +02005218 max_len = mfl;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005219 }
Manuel Pégourié-Gonnard9468ff12017-09-21 13:49:50 +02005220#endif
5221
5222#if defined(MBEDTLS_SSL_PROTO_DTLS)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005223 if (mbedtls_ssl_get_current_mtu(ssl) != 0) {
5224 const size_t mtu = mbedtls_ssl_get_current_mtu(ssl);
5225 const int ret = mbedtls_ssl_get_record_expansion(ssl);
Manuel Pégourié-Gonnard9468ff12017-09-21 13:49:50 +02005226 const size_t overhead = (size_t) ret;
5227
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005228 if (ret < 0) {
5229 return ret;
Manuel Pégourié-Gonnard9468ff12017-09-21 13:49:50 +02005230 }
5231
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005232 if (mtu <= overhead) {
5233 MBEDTLS_SSL_DEBUG_MSG(1, ("MTU too low for record expansion"));
5234 return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
5235 }
5236
5237 if (max_len > mtu - overhead) {
Manuel Pégourié-Gonnard9468ff12017-09-21 13:49:50 +02005238 max_len = mtu - overhead;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005239 }
Manuel Pégourié-Gonnard9468ff12017-09-21 13:49:50 +02005240 }
Manuel Pégourié-Gonnardb8eec192018-08-20 09:34:02 +02005241#endif /* MBEDTLS_SSL_PROTO_DTLS */
Manuel Pégourié-Gonnard9468ff12017-09-21 13:49:50 +02005242
Hanno Becker0defedb2018-08-10 12:35:02 +01005243#if !defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) && \
5244 !defined(MBEDTLS_SSL_PROTO_DTLS)
5245 ((void) ssl);
Manuel Pégourié-Gonnard9468ff12017-09-21 13:49:50 +02005246#endif
5247
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005248 return (int) max_len;
Manuel Pégourié-Gonnard9468ff12017-09-21 13:49:50 +02005249}
5250
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005251#if defined(MBEDTLS_X509_CRT_PARSE_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005252const mbedtls_x509_crt *mbedtls_ssl_get_peer_cert(const mbedtls_ssl_context *ssl)
Paul Bakkerb0550d92012-10-30 07:51:03 +00005253{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005254 if (ssl == NULL || ssl->session == NULL) {
5255 return NULL;
5256 }
Paul Bakkerb0550d92012-10-30 07:51:03 +00005257
Hanno Beckere6824572019-02-07 13:18:46 +00005258#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005259 return ssl->session->peer_cert;
Hanno Beckere6824572019-02-07 13:18:46 +00005260#else
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005261 return NULL;
Hanno Beckere6824572019-02-07 13:18:46 +00005262#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
Paul Bakkerb0550d92012-10-30 07:51:03 +00005263}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005264#endif /* MBEDTLS_X509_CRT_PARSE_C */
Paul Bakkerb0550d92012-10-30 07:51:03 +00005265
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005266#if defined(MBEDTLS_SSL_CLI_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005267int mbedtls_ssl_get_session(const mbedtls_ssl_context *ssl,
5268 mbedtls_ssl_session *dst)
Manuel Pégourié-Gonnard74718032013-07-30 12:41:56 +02005269{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005270 if (ssl == NULL ||
Manuel Pégourié-Gonnard74718032013-07-30 12:41:56 +02005271 dst == NULL ||
5272 ssl->session == NULL ||
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005273 ssl->conf->endpoint != MBEDTLS_SSL_IS_CLIENT) {
5274 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
Manuel Pégourié-Gonnard74718032013-07-30 12:41:56 +02005275 }
5276
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005277 return mbedtls_ssl_session_copy(dst, ssl->session);
Manuel Pégourié-Gonnard74718032013-07-30 12:41:56 +02005278}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005279#endif /* MBEDTLS_SSL_CLI_C */
Manuel Pégourié-Gonnard74718032013-07-30 12:41:56 +02005280
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005281const mbedtls_ssl_session *mbedtls_ssl_get_session_pointer(const mbedtls_ssl_context *ssl)
Manuel Pégourié-Gonnardb5e4e0a2019-05-20 11:12:28 +02005282{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005283 if (ssl == NULL) {
5284 return NULL;
5285 }
Manuel Pégourié-Gonnardb5e4e0a2019-05-20 11:12:28 +02005286
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005287 return ssl->session;
Manuel Pégourié-Gonnardb5e4e0a2019-05-20 11:12:28 +02005288}
5289
Paul Bakker5121ce52009-01-03 21:22:43 +00005290/*
Hanno Beckera835da52019-05-16 12:39:07 +01005291 * Define ticket header determining Mbed TLS version
5292 * and structure of the ticket.
5293 */
5294
Hanno Becker94ef3b32019-05-16 12:50:45 +01005295/*
Hanno Becker50b59662019-05-28 14:30:45 +01005296 * Define bitflag determining compile-time settings influencing
5297 * structure of serialized SSL sessions.
Hanno Becker94ef3b32019-05-16 12:50:45 +01005298 */
5299
Hanno Becker50b59662019-05-28 14:30:45 +01005300#if defined(MBEDTLS_HAVE_TIME)
Hanno Becker3e088662019-05-29 11:10:18 +01005301#define SSL_SERIALIZED_SESSION_CONFIG_TIME 1
Hanno Becker50b59662019-05-28 14:30:45 +01005302#else
Hanno Becker3e088662019-05-29 11:10:18 +01005303#define SSL_SERIALIZED_SESSION_CONFIG_TIME 0
Hanno Becker94ef3b32019-05-16 12:50:45 +01005304#endif /* MBEDTLS_HAVE_TIME */
5305
5306#if defined(MBEDTLS_X509_CRT_PARSE_C)
Hanno Becker3e088662019-05-29 11:10:18 +01005307#define SSL_SERIALIZED_SESSION_CONFIG_CRT 1
Hanno Becker94ef3b32019-05-16 12:50:45 +01005308#else
Hanno Becker3e088662019-05-29 11:10:18 +01005309#define SSL_SERIALIZED_SESSION_CONFIG_CRT 0
Hanno Becker94ef3b32019-05-16 12:50:45 +01005310#endif /* MBEDTLS_X509_CRT_PARSE_C */
5311
David Horstmanneb77b6f2024-02-13 17:53:35 +00005312#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
David Horstmann11def972024-03-01 11:20:32 +00005313#define SSL_SERIALIZED_SESSION_CONFIG_KEEP_PEER_CRT 1
David Horstmanneb77b6f2024-02-13 17:53:35 +00005314#else
David Horstmann11def972024-03-01 11:20:32 +00005315#define SSL_SERIALIZED_SESSION_CONFIG_KEEP_PEER_CRT 0
David Horstmanneb77b6f2024-02-13 17:53:35 +00005316#endif /* MBEDTLS_SSL_SESSION_TICKETS */
5317
Hanno Becker94ef3b32019-05-16 12:50:45 +01005318#if defined(MBEDTLS_SSL_CLI_C) && defined(MBEDTLS_SSL_SESSION_TICKETS)
Hanno Becker3e088662019-05-29 11:10:18 +01005319#define SSL_SERIALIZED_SESSION_CONFIG_CLIENT_TICKET 1
Hanno Becker94ef3b32019-05-16 12:50:45 +01005320#else
Hanno Becker3e088662019-05-29 11:10:18 +01005321#define SSL_SERIALIZED_SESSION_CONFIG_CLIENT_TICKET 0
Hanno Becker94ef3b32019-05-16 12:50:45 +01005322#endif /* MBEDTLS_SSL_CLI_C && MBEDTLS_SSL_SESSION_TICKETS */
5323
5324#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
Hanno Becker3e088662019-05-29 11:10:18 +01005325#define SSL_SERIALIZED_SESSION_CONFIG_MFL 1
Hanno Becker94ef3b32019-05-16 12:50:45 +01005326#else
Hanno Becker3e088662019-05-29 11:10:18 +01005327#define SSL_SERIALIZED_SESSION_CONFIG_MFL 0
Hanno Becker94ef3b32019-05-16 12:50:45 +01005328#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
5329
5330#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
Hanno Becker3e088662019-05-29 11:10:18 +01005331#define SSL_SERIALIZED_SESSION_CONFIG_TRUNC_HMAC 1
Hanno Becker94ef3b32019-05-16 12:50:45 +01005332#else
Hanno Becker3e088662019-05-29 11:10:18 +01005333#define SSL_SERIALIZED_SESSION_CONFIG_TRUNC_HMAC 0
Hanno Becker94ef3b32019-05-16 12:50:45 +01005334#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
5335
5336#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
Hanno Becker3e088662019-05-29 11:10:18 +01005337#define SSL_SERIALIZED_SESSION_CONFIG_ETM 1
Hanno Becker94ef3b32019-05-16 12:50:45 +01005338#else
Hanno Becker3e088662019-05-29 11:10:18 +01005339#define SSL_SERIALIZED_SESSION_CONFIG_ETM 0
Hanno Becker94ef3b32019-05-16 12:50:45 +01005340#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
5341
Hanno Becker94ef3b32019-05-16 12:50:45 +01005342#if defined(MBEDTLS_SSL_SESSION_TICKETS)
5343#define SSL_SERIALIZED_SESSION_CONFIG_TICKET 1
5344#else
5345#define SSL_SERIALIZED_SESSION_CONFIG_TICKET 0
5346#endif /* MBEDTLS_SSL_SESSION_TICKETS */
5347
Hanno Becker3e088662019-05-29 11:10:18 +01005348#define SSL_SERIALIZED_SESSION_CONFIG_TIME_BIT 0
5349#define SSL_SERIALIZED_SESSION_CONFIG_CRT_BIT 1
5350#define SSL_SERIALIZED_SESSION_CONFIG_CLIENT_TICKET_BIT 2
5351#define SSL_SERIALIZED_SESSION_CONFIG_MFL_BIT 3
5352#define SSL_SERIALIZED_SESSION_CONFIG_TRUNC_HMAC_BIT 4
5353#define SSL_SERIALIZED_SESSION_CONFIG_ETM_BIT 5
5354#define SSL_SERIALIZED_SESSION_CONFIG_TICKET_BIT 6
David Horstmann11def972024-03-01 11:20:32 +00005355#define SSL_SERIALIZED_SESSION_CONFIG_KEEP_PEER_CRT_BIT 7
Hanno Becker3e088662019-05-29 11:10:18 +01005356
Hanno Becker50b59662019-05-28 14:30:45 +01005357#define SSL_SERIALIZED_SESSION_CONFIG_BITFLAG \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005358 ((uint16_t) ( \
5359 (SSL_SERIALIZED_SESSION_CONFIG_TIME << SSL_SERIALIZED_SESSION_CONFIG_TIME_BIT) | \
5360 (SSL_SERIALIZED_SESSION_CONFIG_CRT << SSL_SERIALIZED_SESSION_CONFIG_CRT_BIT) | \
5361 (SSL_SERIALIZED_SESSION_CONFIG_CLIENT_TICKET << \
5362 SSL_SERIALIZED_SESSION_CONFIG_CLIENT_TICKET_BIT) | \
5363 (SSL_SERIALIZED_SESSION_CONFIG_MFL << SSL_SERIALIZED_SESSION_CONFIG_MFL_BIT) | \
5364 (SSL_SERIALIZED_SESSION_CONFIG_TRUNC_HMAC << \
5365 SSL_SERIALIZED_SESSION_CONFIG_TRUNC_HMAC_BIT) | \
5366 (SSL_SERIALIZED_SESSION_CONFIG_ETM << SSL_SERIALIZED_SESSION_CONFIG_ETM_BIT) | \
David Horstmanneb77b6f2024-02-13 17:53:35 +00005367 (SSL_SERIALIZED_SESSION_CONFIG_TICKET << SSL_SERIALIZED_SESSION_CONFIG_TICKET_BIT) | \
David Horstmannf5a6fa22024-03-01 12:31:35 +00005368 (SSL_SERIALIZED_SESSION_CONFIG_KEEP_PEER_CRT << \
5369 SSL_SERIALIZED_SESSION_CONFIG_KEEP_PEER_CRT_BIT)))
Hanno Becker94ef3b32019-05-16 12:50:45 +01005370
Chien Wongb6d57932024-02-07 21:48:12 +08005371static const unsigned char ssl_serialized_session_header[] = {
Hanno Becker94ef3b32019-05-16 12:50:45 +01005372 MBEDTLS_VERSION_MAJOR,
5373 MBEDTLS_VERSION_MINOR,
5374 MBEDTLS_VERSION_PATCH,
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005375 MBEDTLS_BYTE_1(SSL_SERIALIZED_SESSION_CONFIG_BITFLAG),
5376 MBEDTLS_BYTE_0(SSL_SERIALIZED_SESSION_CONFIG_BITFLAG),
Hanno Beckerf8787072019-05-16 12:41:07 +01005377};
Hanno Beckera835da52019-05-16 12:39:07 +01005378
5379/*
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005380 * Serialize a session in the following format:
Manuel Pégourié-Gonnard35eb8022019-05-16 11:11:08 +02005381 * (in the presentation language of TLS, RFC 8446 section 3)
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005382 *
Hanno Becker50b59662019-05-28 14:30:45 +01005383 * opaque mbedtls_version[3]; // major, minor, patch
5384 * opaque session_format[2]; // version-specific 16-bit field determining
5385 * // the format of the remaining
5386 * // serialized data.
Hanno Beckerdc28b6c2019-05-29 11:08:00 +01005387 *
5388 * Note: When updating the format, remember to keep
5389 * these version+format bytes.
5390 *
Hanno Beckerbe34e8e2019-06-04 09:43:16 +01005391 * // In this version, `session_format` determines
5392 * // the setting of those compile-time
5393 * // configuration options which influence
Hanno Becker50b59662019-05-28 14:30:45 +01005394 * // the structure of mbedtls_ssl_session.
David Horstmann363db772024-03-01 12:11:24 +00005395 * #if defined(MBEDTLS_HAVE_TIME)
5396 * uint64 start_time;
5397 * #endif
5398 * uint8 ciphersuite[2]; // defined by the standard
5399 * uint8 compression; // 0 or 1
5400 * uint8 session_id_len; // at most 32
5401 * opaque session_id[32];
5402 * opaque master[48]; // fixed length in the standard
5403 * uint32 verify_result;
David Horstmannfc8cacf2024-03-04 16:37:02 +00005404 * #if defined(MBEDTLS_X509_CRT_PARSE_C)
David Horstmann363db772024-03-01 12:11:24 +00005405 * #if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
5406 * opaque peer_cert<0..2^24-1>; // length 0 means no peer cert
5407 * #else
5408 * uint8 peer_cert_digest_type;
5409 * opaque peer_cert_digest<0..2^8-1>
5410 * #endif
David Horstmannfc8cacf2024-03-04 16:37:02 +00005411 * #endif
5412 * #if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
David Horstmann363db772024-03-01 12:11:24 +00005413 * opaque ticket<0..2^24-1>; // length 0 means no ticket
5414 * uint32 ticket_lifetime;
5415 * #endif
5416 * #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
5417 * uint8 mfl_code; // up to 255 according to standard
5418 * #endif
5419 * #if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
5420 * uint8 trunc_hmac; // 0 or 1
5421 * #endif
5422 * #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
5423 * uint8 encrypt_then_mac; // 0 or 1
5424 * #endif
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005425 *
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005426 * The order is the same as in the definition of the structure, except
5427 * verify_result is put before peer_cert so that all mandatory fields come
5428 * together in one block.
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005429 */
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +02005430MBEDTLS_CHECK_RETURN_CRITICAL
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005431static int ssl_session_save(const mbedtls_ssl_session *session,
5432 unsigned char omit_header,
5433 unsigned char *buf,
5434 size_t buf_len,
5435 size_t *olen)
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005436{
5437 unsigned char *p = buf;
Manuel Pégourié-Gonnard26f982f2019-05-21 11:01:32 +02005438 size_t used = 0;
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005439#if defined(MBEDTLS_HAVE_TIME)
5440 uint64_t start;
5441#endif
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005442#if defined(MBEDTLS_X509_CRT_PARSE_C)
5443#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
5444 size_t cert_len;
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005445#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
5446#endif /* MBEDTLS_X509_CRT_PARSE_C */
5447
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005448
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005449 if (!omit_header) {
Manuel Pégourié-Gonnard45ac1f02019-07-23 16:52:45 +02005450 /*
5451 * Add version identifier
5452 */
5453
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005454 used += sizeof(ssl_serialized_session_header);
Manuel Pégourié-Gonnard45ac1f02019-07-23 16:52:45 +02005455
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005456 if (used <= buf_len) {
5457 memcpy(p, ssl_serialized_session_header,
5458 sizeof(ssl_serialized_session_header));
5459 p += sizeof(ssl_serialized_session_header);
Manuel Pégourié-Gonnard45ac1f02019-07-23 16:52:45 +02005460 }
Hanno Beckera835da52019-05-16 12:39:07 +01005461 }
5462
5463 /*
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005464 * Time
5465 */
5466#if defined(MBEDTLS_HAVE_TIME)
5467 used += 8;
5468
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005469 if (used <= buf_len) {
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005470 start = (uint64_t) session->start;
5471
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005472 MBEDTLS_PUT_UINT64_BE(start, p, 0);
Joe Subbiani2f98d792021-08-20 11:44:44 +01005473 p += 8;
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005474 }
5475#endif /* MBEDTLS_HAVE_TIME */
5476
5477 /*
5478 * Basic mandatory fields
5479 */
5480 used += 2 /* ciphersuite */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005481 + 1 /* compression */
5482 + 1 /* id_len */
5483 + sizeof(session->id)
5484 + sizeof(session->master)
5485 + 4; /* verify_result */
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005486
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005487 if (used <= buf_len) {
5488 MBEDTLS_PUT_UINT16_BE(session->ciphersuite, p, 0);
Joe Subbiani2f98d792021-08-20 11:44:44 +01005489 p += 2;
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005490
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005491 *p++ = MBEDTLS_BYTE_0(session->compression);
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005492
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005493 *p++ = MBEDTLS_BYTE_0(session->id_len);
5494 memcpy(p, session->id, 32);
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005495 p += 32;
5496
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005497 memcpy(p, session->master, 48);
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005498 p += 48;
5499
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005500 MBEDTLS_PUT_UINT32_BE(session->verify_result, p, 0);
Joe Subbiani2f98d792021-08-20 11:44:44 +01005501 p += 4;
Manuel Pégourié-Gonnard26f982f2019-05-21 11:01:32 +02005502 }
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005503
Manuel Pégourié-Gonnard35eb8022019-05-16 11:11:08 +02005504 /*
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005505 * Peer's end-entity certificate
Manuel Pégourié-Gonnard35eb8022019-05-16 11:11:08 +02005506 */
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005507#if defined(MBEDTLS_X509_CRT_PARSE_C)
5508#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005509 if (session->peer_cert == NULL) {
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005510 cert_len = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005511 } else {
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005512 cert_len = session->peer_cert->raw.len;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005513 }
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005514
Manuel Pégourié-Gonnard26f982f2019-05-21 11:01:32 +02005515 used += 3 + cert_len;
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005516
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005517 if (used <= buf_len) {
5518 *p++ = MBEDTLS_BYTE_2(cert_len);
5519 *p++ = MBEDTLS_BYTE_1(cert_len);
5520 *p++ = MBEDTLS_BYTE_0(cert_len);
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005521
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005522 if (session->peer_cert != NULL) {
5523 memcpy(p, session->peer_cert->raw.p, cert_len);
Manuel Pégourié-Gonnard26f982f2019-05-21 11:01:32 +02005524 p += cert_len;
5525 }
5526 }
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005527#else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005528 if (session->peer_cert_digest != NULL) {
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005529 used += 1 /* type */ + 1 /* length */ + session->peer_cert_digest_len;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005530 if (used <= buf_len) {
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005531 *p++ = (unsigned char) session->peer_cert_digest_type;
5532 *p++ = (unsigned char) session->peer_cert_digest_len;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005533 memcpy(p, session->peer_cert_digest,
5534 session->peer_cert_digest_len);
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005535 p += session->peer_cert_digest_len;
5536 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005537 } else {
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005538 used += 2;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005539 if (used <= buf_len) {
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005540 *p++ = (unsigned char) MBEDTLS_MD_NONE;
5541 *p++ = 0;
5542 }
Manuel Pégourié-Gonnard26f982f2019-05-21 11:01:32 +02005543 }
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005544#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
5545#endif /* MBEDTLS_X509_CRT_PARSE_C */
5546
Manuel Pégourié-Gonnard35eb8022019-05-16 11:11:08 +02005547 /*
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005548 * Session ticket if any, plus associated data
Manuel Pégourié-Gonnard35eb8022019-05-16 11:11:08 +02005549 */
5550#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005551 used += 3 + session->ticket_len + 4; /* len + ticket + lifetime */
Manuel Pégourié-Gonnard35eb8022019-05-16 11:11:08 +02005552
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005553 if (used <= buf_len) {
5554 *p++ = MBEDTLS_BYTE_2(session->ticket_len);
5555 *p++ = MBEDTLS_BYTE_1(session->ticket_len);
5556 *p++ = MBEDTLS_BYTE_0(session->ticket_len);
Manuel Pégourié-Gonnard26f982f2019-05-21 11:01:32 +02005557
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005558 if (session->ticket != NULL) {
5559 memcpy(p, session->ticket, session->ticket_len);
Manuel Pégourié-Gonnard26f982f2019-05-21 11:01:32 +02005560 p += session->ticket_len;
5561 }
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005562
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005563 MBEDTLS_PUT_UINT32_BE(session->ticket_lifetime, p, 0);
Joe Subbiani2f98d792021-08-20 11:44:44 +01005564 p += 4;
Manuel Pégourié-Gonnard35eb8022019-05-16 11:11:08 +02005565 }
5566#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */
5567
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005568 /*
5569 * Misc extension-related info
5570 */
5571#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
5572 used += 1;
5573
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005574 if (used <= buf_len) {
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005575 *p++ = session->mfl_code;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005576 }
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005577#endif
5578
5579#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
5580 used += 1;
5581
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005582 if (used <= buf_len) {
5583 *p++ = (unsigned char) ((session->trunc_hmac) & 0xFF);
5584 }
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005585#endif
5586
5587#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
5588 used += 1;
5589
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005590 if (used <= buf_len) {
5591 *p++ = MBEDTLS_BYTE_0(session->encrypt_then_mac);
5592 }
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005593#endif
5594
Manuel Pégourié-Gonnard35eb8022019-05-16 11:11:08 +02005595 /* Done */
Manuel Pégourié-Gonnard26f982f2019-05-21 11:01:32 +02005596 *olen = used;
5597
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005598 if (used > buf_len) {
5599 return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL;
5600 }
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005601
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005602 return 0;
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005603}
5604
5605/*
Manuel Pégourié-Gonnard45ac1f02019-07-23 16:52:45 +02005606 * Public wrapper for ssl_session_save()
5607 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005608int mbedtls_ssl_session_save(const mbedtls_ssl_session *session,
5609 unsigned char *buf,
5610 size_t buf_len,
5611 size_t *olen)
Manuel Pégourié-Gonnard45ac1f02019-07-23 16:52:45 +02005612{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005613 return ssl_session_save(session, 0, buf, buf_len, olen);
Manuel Pégourié-Gonnard45ac1f02019-07-23 16:52:45 +02005614}
5615
5616/*
Manuel Pégourié-Gonnardb9dfc9f2019-07-12 10:50:19 +02005617 * Deserialize session, see mbedtls_ssl_session_save() for format.
Manuel Pégourié-Gonnarda3d831b2019-05-23 12:28:45 +02005618 *
5619 * This internal version is wrapped by a public function that cleans up in
Manuel Pégourié-Gonnard45ac1f02019-07-23 16:52:45 +02005620 * case of error, and has an extra option omit_header.
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005621 */
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +02005622MBEDTLS_CHECK_RETURN_CRITICAL
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005623static int ssl_session_load(mbedtls_ssl_session *session,
5624 unsigned char omit_header,
5625 const unsigned char *buf,
5626 size_t len)
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005627{
5628 const unsigned char *p = buf;
5629 const unsigned char * const end = buf + len;
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005630#if defined(MBEDTLS_HAVE_TIME)
5631 uint64_t start;
5632#endif
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005633#if defined(MBEDTLS_X509_CRT_PARSE_C)
5634#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
5635 size_t cert_len;
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005636#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
5637#endif /* MBEDTLS_X509_CRT_PARSE_C */
5638
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005639 if (!omit_header) {
Manuel Pégourié-Gonnard45ac1f02019-07-23 16:52:45 +02005640 /*
5641 * Check version identifier
5642 */
5643
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005644 if ((size_t) (end - p) < sizeof(ssl_serialized_session_header)) {
5645 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
Manuel Pégourié-Gonnard45ac1f02019-07-23 16:52:45 +02005646 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005647
5648 if (memcmp(p, ssl_serialized_session_header,
5649 sizeof(ssl_serialized_session_header)) != 0) {
5650 return MBEDTLS_ERR_SSL_VERSION_MISMATCH;
5651 }
5652 p += sizeof(ssl_serialized_session_header);
Hanno Beckera835da52019-05-16 12:39:07 +01005653 }
Hanno Beckera835da52019-05-16 12:39:07 +01005654
5655 /*
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005656 * Time
Manuel Pégourié-Gonnard35eb8022019-05-16 11:11:08 +02005657 */
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005658#if defined(MBEDTLS_HAVE_TIME)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005659 if (8 > (size_t) (end - p)) {
5660 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
5661 }
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005662
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005663 start = ((uint64_t) p[0] << 56) |
5664 ((uint64_t) p[1] << 48) |
5665 ((uint64_t) p[2] << 40) |
5666 ((uint64_t) p[3] << 32) |
5667 ((uint64_t) p[4] << 24) |
5668 ((uint64_t) p[5] << 16) |
5669 ((uint64_t) p[6] << 8) |
5670 ((uint64_t) p[7]);
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005671 p += 8;
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005672
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005673 session->start = (time_t) start;
5674#endif /* MBEDTLS_HAVE_TIME */
5675
5676 /*
5677 * Basic mandatory fields
5678 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005679 if (2 + 1 + 1 + 32 + 48 + 4 > (size_t) (end - p)) {
5680 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
5681 }
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005682
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005683 session->ciphersuite = (p[0] << 8) | p[1];
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005684 p += 2;
5685
5686 session->compression = *p++;
5687
5688 session->id_len = *p++;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005689 memcpy(session->id, p, 32);
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005690 p += 32;
5691
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005692 memcpy(session->master, p, 48);
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005693 p += 48;
5694
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005695 session->verify_result = ((uint32_t) p[0] << 24) |
5696 ((uint32_t) p[1] << 16) |
5697 ((uint32_t) p[2] << 8) |
5698 ((uint32_t) p[3]);
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005699 p += 4;
5700
5701 /* Immediately clear invalid pointer values that have been read, in case
5702 * we exit early before we replaced them with valid ones. */
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005703#if defined(MBEDTLS_X509_CRT_PARSE_C)
5704#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
5705 session->peer_cert = NULL;
5706#else
5707 session->peer_cert_digest = NULL;
5708#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
5709#endif /* MBEDTLS_X509_CRT_PARSE_C */
5710#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
5711 session->ticket = NULL;
5712#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */
5713
Manuel Pégourié-Gonnard35eb8022019-05-16 11:11:08 +02005714 /*
5715 * Peer certificate
5716 */
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005717#if defined(MBEDTLS_X509_CRT_PARSE_C)
5718#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
5719 /* Deserialize CRT from the end of the ticket. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005720 if (3 > (size_t) (end - p)) {
5721 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
5722 }
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005723
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005724 cert_len = (p[0] << 16) | (p[1] << 8) | p[2];
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005725 p += 3;
5726
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005727 if (cert_len != 0) {
Janos Follath865b3eb2019-12-16 11:46:15 +00005728 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005729
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005730 if (cert_len > (size_t) (end - p)) {
5731 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
5732 }
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005733
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005734 session->peer_cert = mbedtls_calloc(1, sizeof(mbedtls_x509_crt));
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005735
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005736 if (session->peer_cert == NULL) {
5737 return MBEDTLS_ERR_SSL_ALLOC_FAILED;
5738 }
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005739
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005740 mbedtls_x509_crt_init(session->peer_cert);
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005741
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005742 if ((ret = mbedtls_x509_crt_parse_der(session->peer_cert,
5743 p, cert_len)) != 0) {
5744 mbedtls_x509_crt_free(session->peer_cert);
5745 mbedtls_free(session->peer_cert);
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005746 session->peer_cert = NULL;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005747 return ret;
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005748 }
5749
5750 p += cert_len;
5751 }
5752#else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
5753 /* Deserialize CRT digest from the end of the ticket. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005754 if (2 > (size_t) (end - p)) {
5755 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
5756 }
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005757
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005758 session->peer_cert_digest_type = (mbedtls_md_type_t) *p++;
5759 session->peer_cert_digest_len = (size_t) *p++;
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005760
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005761 if (session->peer_cert_digest_len != 0) {
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005762 const mbedtls_md_info_t *md_info =
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005763 mbedtls_md_info_from_type(session->peer_cert_digest_type);
5764 if (md_info == NULL) {
5765 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
5766 }
5767 if (session->peer_cert_digest_len != mbedtls_md_get_size(md_info)) {
5768 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
5769 }
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005770
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005771 if (session->peer_cert_digest_len > (size_t) (end - p)) {
5772 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
5773 }
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005774
5775 session->peer_cert_digest =
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005776 mbedtls_calloc(1, session->peer_cert_digest_len);
5777 if (session->peer_cert_digest == NULL) {
5778 return MBEDTLS_ERR_SSL_ALLOC_FAILED;
5779 }
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005780
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005781 memcpy(session->peer_cert_digest, p,
5782 session->peer_cert_digest_len);
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005783 p += session->peer_cert_digest_len;
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005784 }
5785#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
5786#endif /* MBEDTLS_X509_CRT_PARSE_C */
5787
Manuel Pégourié-Gonnard35eb8022019-05-16 11:11:08 +02005788 /*
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005789 * Session ticket and associated data
Manuel Pégourié-Gonnard35eb8022019-05-16 11:11:08 +02005790 */
5791#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005792 if (3 > (size_t) (end - p)) {
5793 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
5794 }
Manuel Pégourié-Gonnard35eb8022019-05-16 11:11:08 +02005795
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005796 session->ticket_len = (p[0] << 16) | (p[1] << 8) | p[2];
Manuel Pégourié-Gonnard35eb8022019-05-16 11:11:08 +02005797 p += 3;
5798
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005799 if (session->ticket_len != 0) {
5800 if (session->ticket_len > (size_t) (end - p)) {
5801 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
5802 }
Manuel Pégourié-Gonnard35eb8022019-05-16 11:11:08 +02005803
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005804 session->ticket = mbedtls_calloc(1, session->ticket_len);
5805 if (session->ticket == NULL) {
5806 return MBEDTLS_ERR_SSL_ALLOC_FAILED;
5807 }
Manuel Pégourié-Gonnard35eb8022019-05-16 11:11:08 +02005808
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005809 memcpy(session->ticket, p, session->ticket_len);
Manuel Pégourié-Gonnard35eb8022019-05-16 11:11:08 +02005810 p += session->ticket_len;
5811 }
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005812
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005813 if (4 > (size_t) (end - p)) {
5814 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
5815 }
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005816
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005817 session->ticket_lifetime = ((uint32_t) p[0] << 24) |
5818 ((uint32_t) p[1] << 16) |
5819 ((uint32_t) p[2] << 8) |
5820 ((uint32_t) p[3]);
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005821 p += 4;
Manuel Pégourié-Gonnard35eb8022019-05-16 11:11:08 +02005822#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */
5823
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005824 /*
5825 * Misc extension-related info
5826 */
5827#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005828 if (1 > (size_t) (end - p)) {
5829 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
5830 }
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005831
5832 session->mfl_code = *p++;
5833#endif
5834
5835#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005836 if (1 > (size_t) (end - p)) {
5837 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
5838 }
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005839
5840 session->trunc_hmac = *p++;
5841#endif
5842
5843#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005844 if (1 > (size_t) (end - p)) {
5845 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
5846 }
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005847
5848 session->encrypt_then_mac = *p++;
5849#endif
5850
Manuel Pégourié-Gonnard35eb8022019-05-16 11:11:08 +02005851 /* Done, should have consumed entire buffer */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005852 if (p != end) {
5853 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
5854 }
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005855
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005856 return 0;
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005857}
5858
5859/*
Manuel Pégourié-Gonnardb9dfc9f2019-07-12 10:50:19 +02005860 * Deserialize session: public wrapper for error cleaning
Manuel Pégourié-Gonnarda3d831b2019-05-23 12:28:45 +02005861 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005862int mbedtls_ssl_session_load(mbedtls_ssl_session *session,
5863 const unsigned char *buf,
5864 size_t len)
Manuel Pégourié-Gonnarda3d831b2019-05-23 12:28:45 +02005865{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005866 int ret = ssl_session_load(session, 0, buf, len);
Manuel Pégourié-Gonnarda3d831b2019-05-23 12:28:45 +02005867
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005868 if (ret != 0) {
5869 mbedtls_ssl_session_free(session);
5870 }
Manuel Pégourié-Gonnarda3d831b2019-05-23 12:28:45 +02005871
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005872 return ret;
Manuel Pégourié-Gonnarda3d831b2019-05-23 12:28:45 +02005873}
5874
5875/*
Paul Bakker1961b702013-01-25 14:49:24 +01005876 * Perform a single step of the SSL handshake
Paul Bakker5121ce52009-01-03 21:22:43 +00005877 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005878int mbedtls_ssl_handshake_step(mbedtls_ssl_context *ssl)
Paul Bakker5121ce52009-01-03 21:22:43 +00005879{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005880 int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
Paul Bakker5121ce52009-01-03 21:22:43 +00005881
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005882 if (ssl == NULL || ssl->conf == NULL) {
5883 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
5884 }
Manuel Pégourié-Gonnardf81ee2e2015-09-01 17:43:40 +02005885
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005886#if defined(MBEDTLS_SSL_CLI_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005887 if (ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT) {
5888 ret = mbedtls_ssl_handshake_client_step(ssl);
5889 }
Paul Bakker5121ce52009-01-03 21:22:43 +00005890#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005891#if defined(MBEDTLS_SSL_SRV_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005892 if (ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER) {
5893 ret = mbedtls_ssl_handshake_server_step(ssl);
5894 }
Paul Bakker5121ce52009-01-03 21:22:43 +00005895#endif
5896
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005897 return ret;
Paul Bakker1961b702013-01-25 14:49:24 +01005898}
5899
5900/*
5901 * Perform the SSL handshake
5902 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005903int mbedtls_ssl_handshake(mbedtls_ssl_context *ssl)
Paul Bakker1961b702013-01-25 14:49:24 +01005904{
5905 int ret = 0;
5906
Hanno Beckera817ea42020-10-20 15:20:23 +01005907 /* Sanity checks */
5908
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005909 if (ssl == NULL || ssl->conf == NULL) {
5910 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
5911 }
Manuel Pégourié-Gonnardf81ee2e2015-09-01 17:43:40 +02005912
Hanno Beckera817ea42020-10-20 15:20:23 +01005913#if defined(MBEDTLS_SSL_PROTO_DTLS)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005914 if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
5915 (ssl->f_set_timer == NULL || ssl->f_get_timer == NULL)) {
5916 MBEDTLS_SSL_DEBUG_MSG(1, ("You must use "
5917 "mbedtls_ssl_set_timer_cb() for DTLS"));
5918 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
Hanno Beckera817ea42020-10-20 15:20:23 +01005919 }
5920#endif /* MBEDTLS_SSL_PROTO_DTLS */
5921
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005922 MBEDTLS_SSL_DEBUG_MSG(2, ("=> handshake"));
Paul Bakker1961b702013-01-25 14:49:24 +01005923
Hanno Beckera817ea42020-10-20 15:20:23 +01005924 /* Main handshake loop */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005925 while (ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER) {
5926 ret = mbedtls_ssl_handshake_step(ssl);
Paul Bakker1961b702013-01-25 14:49:24 +01005927
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005928 if (ret != 0) {
Paul Bakker1961b702013-01-25 14:49:24 +01005929 break;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005930 }
Paul Bakker1961b702013-01-25 14:49:24 +01005931 }
5932
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005933 MBEDTLS_SSL_DEBUG_MSG(2, ("<= handshake"));
Paul Bakker5121ce52009-01-03 21:22:43 +00005934
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005935 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00005936}
5937
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005938#if defined(MBEDTLS_SSL_RENEGOTIATION)
5939#if defined(MBEDTLS_SSL_SRV_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00005940/*
Manuel Pégourié-Gonnard214eed32013-10-30 13:06:54 +01005941 * Write HelloRequest to request renegotiation on server
Paul Bakker48916f92012-09-16 19:57:18 +00005942 */
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +02005943MBEDTLS_CHECK_RETURN_CRITICAL
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005944static int ssl_write_hello_request(mbedtls_ssl_context *ssl)
Manuel Pégourié-Gonnard214eed32013-10-30 13:06:54 +01005945{
Janos Follath865b3eb2019-12-16 11:46:15 +00005946 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard214eed32013-10-30 13:06:54 +01005947
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005948 MBEDTLS_SSL_DEBUG_MSG(2, ("=> write hello request"));
Manuel Pégourié-Gonnard214eed32013-10-30 13:06:54 +01005949
5950 ssl->out_msglen = 4;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005951 ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
5952 ssl->out_msg[0] = MBEDTLS_SSL_HS_HELLO_REQUEST;
Manuel Pégourié-Gonnard214eed32013-10-30 13:06:54 +01005953
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005954 if ((ret = mbedtls_ssl_write_handshake_msg(ssl)) != 0) {
5955 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_handshake_msg", ret);
5956 return ret;
Manuel Pégourié-Gonnard214eed32013-10-30 13:06:54 +01005957 }
5958
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005959 MBEDTLS_SSL_DEBUG_MSG(2, ("<= write hello request"));
Manuel Pégourié-Gonnard214eed32013-10-30 13:06:54 +01005960
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005961 return 0;
Manuel Pégourié-Gonnard214eed32013-10-30 13:06:54 +01005962}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005963#endif /* MBEDTLS_SSL_SRV_C */
Manuel Pégourié-Gonnard214eed32013-10-30 13:06:54 +01005964
5965/*
5966 * Actually renegotiate current connection, triggered by either:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005967 * - any side: calling mbedtls_ssl_renegotiate(),
5968 * - client: receiving a HelloRequest during mbedtls_ssl_read(),
5969 * - server: receiving any handshake message on server during mbedtls_ssl_read() after
Manuel Pégourié-Gonnard55e4ff22014-08-19 11:16:35 +02005970 * the initial handshake is completed.
Manuel Pégourié-Gonnard9c1e1892013-10-30 16:41:21 +01005971 * If the handshake doesn't complete due to waiting for I/O, it will continue
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005972 * during the next calls to mbedtls_ssl_renegotiate() or mbedtls_ssl_read() respectively.
Manuel Pégourié-Gonnard214eed32013-10-30 13:06:54 +01005973 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005974int mbedtls_ssl_start_renegotiation(mbedtls_ssl_context *ssl)
Paul Bakker48916f92012-09-16 19:57:18 +00005975{
Janos Follath865b3eb2019-12-16 11:46:15 +00005976 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker48916f92012-09-16 19:57:18 +00005977
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005978 MBEDTLS_SSL_DEBUG_MSG(2, ("=> renegotiate"));
Paul Bakker48916f92012-09-16 19:57:18 +00005979
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005980 if ((ret = ssl_handshake_init(ssl)) != 0) {
5981 return ret;
5982 }
Paul Bakker48916f92012-09-16 19:57:18 +00005983
Manuel Pégourié-Gonnard0557bd52014-08-19 19:18:39 +02005984 /* RFC 6347 4.2.2: "[...] the HelloRequest will have message_seq = 0 and
5985 * the ServerHello will have message_seq = 1" */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005986#if defined(MBEDTLS_SSL_PROTO_DTLS)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005987 if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
5988 ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING) {
5989 if (ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER) {
Manuel Pégourié-Gonnard1aa586e2014-09-03 12:54:04 +02005990 ssl->handshake->out_msg_seq = 1;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005991 } else {
Manuel Pégourié-Gonnard1aa586e2014-09-03 12:54:04 +02005992 ssl->handshake->in_msg_seq = 1;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005993 }
Manuel Pégourié-Gonnard0557bd52014-08-19 19:18:39 +02005994 }
5995#endif
5996
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005997 ssl->state = MBEDTLS_SSL_HELLO_REQUEST;
5998 ssl->renego_status = MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS;
Paul Bakker48916f92012-09-16 19:57:18 +00005999
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006000 if ((ret = mbedtls_ssl_handshake(ssl)) != 0) {
6001 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_handshake", ret);
6002 return ret;
Paul Bakker48916f92012-09-16 19:57:18 +00006003 }
6004
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006005 MBEDTLS_SSL_DEBUG_MSG(2, ("<= renegotiate"));
Paul Bakker48916f92012-09-16 19:57:18 +00006006
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006007 return 0;
Paul Bakker48916f92012-09-16 19:57:18 +00006008}
6009
6010/*
Manuel Pégourié-Gonnard214eed32013-10-30 13:06:54 +01006011 * Renegotiate current connection on client,
6012 * or request renegotiation on server
6013 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006014int mbedtls_ssl_renegotiate(mbedtls_ssl_context *ssl)
Manuel Pégourié-Gonnard214eed32013-10-30 13:06:54 +01006015{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02006016 int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
Manuel Pégourié-Gonnard9c1e1892013-10-30 16:41:21 +01006017
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006018 if (ssl == NULL || ssl->conf == NULL) {
6019 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
6020 }
Manuel Pégourié-Gonnardf81ee2e2015-09-01 17:43:40 +02006021
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02006022#if defined(MBEDTLS_SSL_SRV_C)
Manuel Pégourié-Gonnard9c1e1892013-10-30 16:41:21 +01006023 /* On server, just send the request */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006024 if (ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER) {
6025 if (ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER) {
6026 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
6027 }
Manuel Pégourié-Gonnard9c1e1892013-10-30 16:41:21 +01006028
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02006029 ssl->renego_status = MBEDTLS_SSL_RENEGOTIATION_PENDING;
Manuel Pégourié-Gonnardf07f4212014-08-15 19:04:47 +02006030
6031 /* Did we already try/start sending HelloRequest? */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006032 if (ssl->out_left != 0) {
6033 return mbedtls_ssl_flush_output(ssl);
6034 }
Manuel Pégourié-Gonnardf07f4212014-08-15 19:04:47 +02006035
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006036 return ssl_write_hello_request(ssl);
Manuel Pégourié-Gonnard9c1e1892013-10-30 16:41:21 +01006037 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02006038#endif /* MBEDTLS_SSL_SRV_C */
Manuel Pégourié-Gonnard9c1e1892013-10-30 16:41:21 +01006039
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02006040#if defined(MBEDTLS_SSL_CLI_C)
Manuel Pégourié-Gonnard9c1e1892013-10-30 16:41:21 +01006041 /*
6042 * On client, either start the renegotiation process or,
6043 * if already in progress, continue the handshake
6044 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006045 if (ssl->renego_status != MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS) {
6046 if (ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER) {
6047 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
Manuel Pégourié-Gonnard9c1e1892013-10-30 16:41:21 +01006048 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006049
6050 if ((ret = mbedtls_ssl_start_renegotiation(ssl)) != 0) {
6051 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_start_renegotiation", ret);
6052 return ret;
6053 }
6054 } else {
6055 if ((ret = mbedtls_ssl_handshake(ssl)) != 0) {
6056 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_handshake", ret);
6057 return ret;
Manuel Pégourié-Gonnard9c1e1892013-10-30 16:41:21 +01006058 }
6059 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02006060#endif /* MBEDTLS_SSL_CLI_C */
Manuel Pégourié-Gonnard9c1e1892013-10-30 16:41:21 +01006061
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006062 return ret;
Manuel Pégourié-Gonnard214eed32013-10-30 13:06:54 +01006063}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02006064#endif /* MBEDTLS_SSL_RENEGOTIATION */
Manuel Pégourié-Gonnard214eed32013-10-30 13:06:54 +01006065
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02006066#if defined(MBEDTLS_X509_CRT_PARSE_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006067static void ssl_key_cert_free(mbedtls_ssl_key_cert *key_cert)
Manuel Pégourié-Gonnard705fcca2013-09-23 20:04:20 +02006068{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02006069 mbedtls_ssl_key_cert *cur = key_cert, *next;
Manuel Pégourié-Gonnard705fcca2013-09-23 20:04:20 +02006070
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006071 while (cur != NULL) {
Manuel Pégourié-Gonnard705fcca2013-09-23 20:04:20 +02006072 next = cur->next;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006073 mbedtls_free(cur);
Manuel Pégourié-Gonnard705fcca2013-09-23 20:04:20 +02006074 cur = next;
6075 }
6076}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02006077#endif /* MBEDTLS_X509_CRT_PARSE_C */
Manuel Pégourié-Gonnard705fcca2013-09-23 20:04:20 +02006078
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006079void mbedtls_ssl_handshake_free(mbedtls_ssl_context *ssl)
Paul Bakker48916f92012-09-16 19:57:18 +00006080{
Gilles Peskine9b562d52018-04-25 20:32:43 +02006081 mbedtls_ssl_handshake_params *handshake = ssl->handshake;
6082
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006083 if (handshake == NULL) {
Paul Bakkeraccaffe2014-06-26 13:37:14 +02006084 return;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006085 }
Paul Bakkeraccaffe2014-06-26 13:37:14 +02006086
Gilles Peskinedf13d5c2018-04-25 20:39:48 +02006087#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006088 if (ssl->conf->f_async_cancel != NULL && handshake->async_in_progress != 0) {
6089 ssl->conf->f_async_cancel(ssl);
Gilles Peskinedf13d5c2018-04-25 20:39:48 +02006090 handshake->async_in_progress = 0;
6091 }
6092#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
6093
Manuel Pégourié-Gonnardb9d64e52015-07-06 14:18:56 +02006094#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
6095 defined(MBEDTLS_SSL_PROTO_TLS1_1)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006096 mbedtls_md5_free(&handshake->fin_md5);
6097 mbedtls_sha1_free(&handshake->fin_sha1);
Manuel Pégourié-Gonnardb9d64e52015-07-06 14:18:56 +02006098#endif
6099#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
6100#if defined(MBEDTLS_SHA256_C)
Andrzej Kurekeb342242019-01-29 09:14:33 -05006101#if defined(MBEDTLS_USE_PSA_CRYPTO)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006102 psa_hash_abort(&handshake->fin_sha256_psa);
Andrzej Kurekeb342242019-01-29 09:14:33 -05006103#else
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006104 mbedtls_sha256_free(&handshake->fin_sha256);
Manuel Pégourié-Gonnardb9d64e52015-07-06 14:18:56 +02006105#endif
Andrzej Kurekeb342242019-01-29 09:14:33 -05006106#endif
Gilles Peskined2d59372021-05-12 22:43:27 +02006107#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384)
Andrzej Kurekeb342242019-01-29 09:14:33 -05006108#if defined(MBEDTLS_USE_PSA_CRYPTO)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006109 psa_hash_abort(&handshake->fin_sha384_psa);
Andrzej Kurekeb342242019-01-29 09:14:33 -05006110#else
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006111 mbedtls_sha512_free(&handshake->fin_sha512);
Manuel Pégourié-Gonnardb9d64e52015-07-06 14:18:56 +02006112#endif
Andrzej Kurekeb342242019-01-29 09:14:33 -05006113#endif
Manuel Pégourié-Gonnardb9d64e52015-07-06 14:18:56 +02006114#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
6115
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02006116#if defined(MBEDTLS_DHM_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006117 mbedtls_dhm_free(&handshake->dhm_ctx);
Paul Bakker48916f92012-09-16 19:57:18 +00006118#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02006119#if defined(MBEDTLS_ECDH_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006120 mbedtls_ecdh_free(&handshake->ecdh_ctx);
Paul Bakker61d113b2013-07-04 11:51:43 +02006121#endif
Manuel Pégourié-Gonnardeef142d2015-09-16 10:05:04 +02006122#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006123 mbedtls_ecjpake_free(&handshake->ecjpake_ctx);
Manuel Pégourié-Gonnard77c06462015-09-17 13:59:49 +02006124#if defined(MBEDTLS_SSL_CLI_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006125 mbedtls_free(handshake->ecjpake_cache);
Manuel Pégourié-Gonnard77c06462015-09-17 13:59:49 +02006126 handshake->ecjpake_cache = NULL;
6127 handshake->ecjpake_cache_len = 0;
6128#endif
Manuel Pégourié-Gonnard76cfd3f2015-09-15 12:10:54 +02006129#endif
Paul Bakker61d113b2013-07-04 11:51:43 +02006130
Janos Follath4ae5c292016-02-10 11:27:43 +00006131#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
6132 defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
Paul Bakker9af723c2014-05-01 13:03:14 +02006133 /* explicit void pointer cast for buggy MS compiler */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006134 mbedtls_free((void *) handshake->curves);
Manuel Pégourié-Gonnardd09453c2013-09-23 19:11:32 +02006135#endif
6136
Gilles Peskineeccd8882020-03-10 12:19:08 +01006137#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006138 if (handshake->psk != NULL) {
6139 mbedtls_platform_zeroize(handshake->psk, handshake->psk_len);
6140 mbedtls_free(handshake->psk);
Manuel Pégourié-Gonnard4b682962015-05-07 15:59:54 +01006141 }
6142#endif
6143
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02006144#if defined(MBEDTLS_X509_CRT_PARSE_C) && \
6145 defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
Manuel Pégourié-Gonnard83724542013-09-24 22:30:56 +02006146 /*
6147 * Free only the linked list wrapper, not the keys themselves
6148 * since the belong to the SNI callback
6149 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006150 if (handshake->sni_key_cert != NULL) {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02006151 mbedtls_ssl_key_cert *cur = handshake->sni_key_cert, *next;
Manuel Pégourié-Gonnard83724542013-09-24 22:30:56 +02006152
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006153 while (cur != NULL) {
Manuel Pégourié-Gonnard83724542013-09-24 22:30:56 +02006154 next = cur->next;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006155 mbedtls_free(cur);
Manuel Pégourié-Gonnard83724542013-09-24 22:30:56 +02006156 cur = next;
6157 }
6158 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02006159#endif /* MBEDTLS_X509_CRT_PARSE_C && MBEDTLS_SSL_SERVER_NAME_INDICATION */
Manuel Pégourié-Gonnard705fcca2013-09-23 20:04:20 +02006160
Gilles Peskineeccd8882020-03-10 12:19:08 +01006161#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006162 mbedtls_x509_crt_restart_free(&handshake->ecrs_ctx);
6163 if (handshake->ecrs_peer_cert != NULL) {
6164 mbedtls_x509_crt_free(handshake->ecrs_peer_cert);
6165 mbedtls_free(handshake->ecrs_peer_cert);
Hanno Becker3dad3112019-02-05 17:19:52 +00006166 }
Manuel Pégourié-Gonnard862cde52017-05-17 11:56:15 +02006167#endif
6168
Hanno Becker75173122019-02-06 16:18:31 +00006169#if defined(MBEDTLS_X509_CRT_PARSE_C) && \
6170 !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006171 mbedtls_pk_free(&handshake->peer_pubkey);
Hanno Becker75173122019-02-06 16:18:31 +00006172#endif /* MBEDTLS_X509_CRT_PARSE_C && !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
6173
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02006174#if defined(MBEDTLS_SSL_PROTO_DTLS)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006175 mbedtls_free(handshake->verify_cookie);
6176 mbedtls_ssl_flight_free(handshake->flight);
6177 mbedtls_ssl_buffering_free(ssl);
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +02006178#endif
6179
Hanno Becker4a63ed42019-01-08 11:39:35 +00006180#if defined(MBEDTLS_ECDH_C) && \
6181 defined(MBEDTLS_USE_PSA_CRYPTO)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006182 psa_destroy_key(handshake->ecdh_psa_privkey);
Hanno Becker4a63ed42019-01-08 11:39:35 +00006183#endif /* MBEDTLS_ECDH_C && MBEDTLS_USE_PSA_CRYPTO */
6184
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006185 mbedtls_platform_zeroize(handshake,
6186 sizeof(mbedtls_ssl_handshake_params));
Andrzej Kurek0afa2a12020-03-03 10:39:58 -05006187
6188#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
6189 /* If the buffers are too big - reallocate. Because of the way Mbed TLS
6190 * processes datagrams and the fact that a datagram is allowed to have
6191 * several records in it, it is possible that the I/O buffers are not
6192 * empty at this stage */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006193 handle_buffer_resizing(ssl, 1, mbedtls_ssl_get_input_buflen(ssl),
6194 mbedtls_ssl_get_output_buflen(ssl));
Andrzej Kurek0afa2a12020-03-03 10:39:58 -05006195#endif
Paul Bakker48916f92012-09-16 19:57:18 +00006196}
6197
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006198void mbedtls_ssl_session_free(mbedtls_ssl_session *session)
Paul Bakker48916f92012-09-16 19:57:18 +00006199{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006200 if (session == NULL) {
Paul Bakkeraccaffe2014-06-26 13:37:14 +02006201 return;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006202 }
Paul Bakkeraccaffe2014-06-26 13:37:14 +02006203
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02006204#if defined(MBEDTLS_X509_CRT_PARSE_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006205 ssl_clear_peer_cert(session);
Paul Bakkered27a042013-04-18 22:46:23 +02006206#endif
Paul Bakker0a597072012-09-25 21:55:46 +00006207
Manuel Pégourié-Gonnardb596abf2015-05-20 10:45:29 +02006208#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006209 mbedtls_free(session->ticket);
Paul Bakkera503a632013-08-14 13:48:06 +02006210#endif
Manuel Pégourié-Gonnard75d44012013-08-02 14:44:04 +02006211
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006212 mbedtls_platform_zeroize(session, sizeof(mbedtls_ssl_session));
Paul Bakker48916f92012-09-16 19:57:18 +00006213}
6214
Manuel Pégourié-Gonnard5c0e3772019-07-23 16:13:17 +02006215#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION)
Manuel Pégourié-Gonnard4e9370b2019-07-23 16:31:16 +02006216
6217#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
6218#define SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_CONNECTION_ID 1u
6219#else
6220#define SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_CONNECTION_ID 0u
6221#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
6222
6223#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT)
6224#define SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_BADMAC_LIMIT 1u
6225#else
6226#define SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_BADMAC_LIMIT 0u
6227#endif /* MBEDTLS_SSL_DTLS_BADMAC_LIMIT */
6228
6229#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
6230#define SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_ANTI_REPLAY 1u
6231#else
6232#define SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_ANTI_REPLAY 0u
6233#endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */
6234
6235#if defined(MBEDTLS_SSL_ALPN)
6236#define SSL_SERIALIZED_CONTEXT_CONFIG_ALPN 1u
6237#else
6238#define SSL_SERIALIZED_CONTEXT_CONFIG_ALPN 0u
6239#endif /* MBEDTLS_SSL_ALPN */
6240
6241#define SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_CONNECTION_ID_BIT 0
6242#define SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_BADMAC_LIMIT_BIT 1
6243#define SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_ANTI_REPLAY_BIT 2
6244#define SSL_SERIALIZED_CONTEXT_CONFIG_ALPN_BIT 3
6245
6246#define SSL_SERIALIZED_CONTEXT_CONFIG_BITFLAG \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006247 ((uint32_t) ( \
6248 (SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_CONNECTION_ID << \
6249 SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_CONNECTION_ID_BIT) | \
6250 (SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_BADMAC_LIMIT << \
6251 SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_BADMAC_LIMIT_BIT) | \
6252 (SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_ANTI_REPLAY << \
6253 SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_ANTI_REPLAY_BIT) | \
6254 (SSL_SERIALIZED_CONTEXT_CONFIG_ALPN << SSL_SERIALIZED_CONTEXT_CONFIG_ALPN_BIT) | \
6255 0u))
Manuel Pégourié-Gonnard4e9370b2019-07-23 16:31:16 +02006256
Chien Wongb6d57932024-02-07 21:48:12 +08006257static const unsigned char ssl_serialized_context_header[] = {
Manuel Pégourié-Gonnard4c90e852019-07-11 10:58:10 +02006258 MBEDTLS_VERSION_MAJOR,
6259 MBEDTLS_VERSION_MINOR,
6260 MBEDTLS_VERSION_PATCH,
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006261 MBEDTLS_BYTE_1(SSL_SERIALIZED_SESSION_CONFIG_BITFLAG),
6262 MBEDTLS_BYTE_0(SSL_SERIALIZED_SESSION_CONFIG_BITFLAG),
6263 MBEDTLS_BYTE_2(SSL_SERIALIZED_CONTEXT_CONFIG_BITFLAG),
6264 MBEDTLS_BYTE_1(SSL_SERIALIZED_CONTEXT_CONFIG_BITFLAG),
6265 MBEDTLS_BYTE_0(SSL_SERIALIZED_CONTEXT_CONFIG_BITFLAG),
Manuel Pégourié-Gonnard4c90e852019-07-11 10:58:10 +02006266};
6267
Paul Bakker5121ce52009-01-03 21:22:43 +00006268/*
Manuel Pégourié-Gonnardac87e282019-05-28 13:02:16 +02006269 * Serialize a full SSL context
Manuel Pégourié-Gonnard00400c22019-07-10 14:58:45 +02006270 *
6271 * The format of the serialized data is:
6272 * (in the presentation language of TLS, RFC 8446 section 3)
6273 *
6274 * // header
6275 * opaque mbedtls_version[3]; // major, minor, patch
Manuel Pégourié-Gonnard4c90e852019-07-11 10:58:10 +02006276 * opaque context_format[5]; // version-specific field determining
Manuel Pégourié-Gonnard00400c22019-07-10 14:58:45 +02006277 * // the format of the remaining
Manuel Pégourié-Gonnard4c90e852019-07-11 10:58:10 +02006278 * // serialized data.
Manuel Pégourié-Gonnard4e9370b2019-07-23 16:31:16 +02006279 * Note: When updating the format, remember to keep these
6280 * version+format bytes. (We may make their size part of the API.)
Manuel Pégourié-Gonnard00400c22019-07-10 14:58:45 +02006281 *
6282 * // session sub-structure
6283 * opaque session<1..2^32-1>; // see mbedtls_ssl_session_save()
6284 * // transform sub-structure
6285 * uint8 random[64]; // ServerHello.random+ClientHello.random
6286 * uint8 in_cid<0..2^8-1> // Connection ID: expected incoming value
6287 * uint8 out_cid<0..2^8-1> // Connection ID: outgoing value to use
6288 * // fields from ssl_context
6289 * uint32 badmac_seen; // DTLS: number of records with failing MAC
6290 * uint64 in_window_top; // DTLS: last validated record seq_num
6291 * uint64 in_window; // DTLS: bitmask for replay protection
6292 * uint8 disable_datagram_packing; // DTLS: only one record per datagram
6293 * uint64 cur_out_ctr; // Record layer: outgoing sequence number
6294 * uint16 mtu; // DTLS: path mtu (max outgoing fragment size)
6295 * uint8 alpn_chosen<0..2^8-1> // ALPN: negotiated application protocol
6296 *
6297 * Note that many fields of the ssl_context or sub-structures are not
6298 * serialized, as they fall in one of the following categories:
6299 *
6300 * 1. forced value (eg in_left must be 0)
6301 * 2. pointer to dynamically-allocated memory (eg session, transform)
6302 * 3. value can be re-derived from other data (eg session keys from MS)
6303 * 4. value was temporary (eg content of input buffer)
6304 * 5. value will be provided by the user again (eg I/O callbacks and context)
Manuel Pégourié-Gonnardac87e282019-05-28 13:02:16 +02006305 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006306int mbedtls_ssl_context_save(mbedtls_ssl_context *ssl,
6307 unsigned char *buf,
6308 size_t buf_len,
6309 size_t *olen)
Manuel Pégourié-Gonnardac87e282019-05-28 13:02:16 +02006310{
Manuel Pégourié-Gonnard4c90e852019-07-11 10:58:10 +02006311 unsigned char *p = buf;
6312 size_t used = 0;
Manuel Pégourié-Gonnard4b7e6b92019-07-11 12:50:53 +02006313 size_t session_len;
6314 int ret = 0;
Manuel Pégourié-Gonnard4c90e852019-07-11 10:58:10 +02006315
Manuel Pégourié-Gonnard1aaf6692019-07-10 14:14:05 +02006316 /*
Manuel Pégourié-Gonnarde4588692019-07-29 12:28:52 +02006317 * Enforce usage restrictions, see "return BAD_INPUT_DATA" in
6318 * this function's documentation.
6319 *
6320 * These are due to assumptions/limitations in the implementation. Some of
6321 * them are likely to stay (no handshake in progress) some might go away
6322 * (only DTLS) but are currently used to simplify the implementation.
Manuel Pégourié-Gonnard1aaf6692019-07-10 14:14:05 +02006323 */
Manuel Pégourié-Gonnarde4588692019-07-29 12:28:52 +02006324 /* The initial handshake must be over */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006325 if (ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER) {
6326 MBEDTLS_SSL_DEBUG_MSG(1, ("Initial handshake isn't over"));
6327 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
Jarno Lamsa8c51b7c2019-08-21 13:45:05 +03006328 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006329 if (ssl->handshake != NULL) {
6330 MBEDTLS_SSL_DEBUG_MSG(1, ("Handshake isn't completed"));
6331 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
Jarno Lamsa8c51b7c2019-08-21 13:45:05 +03006332 }
Manuel Pégourié-Gonnarde4588692019-07-29 12:28:52 +02006333 /* Double-check that sub-structures are indeed ready */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006334 if (ssl->transform == NULL || ssl->session == NULL) {
6335 MBEDTLS_SSL_DEBUG_MSG(1, ("Serialised structures aren't ready"));
6336 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
Jarno Lamsa8c51b7c2019-08-21 13:45:05 +03006337 }
Manuel Pégourié-Gonnarde4588692019-07-29 12:28:52 +02006338 /* There must be no pending incoming or outgoing data */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006339 if (mbedtls_ssl_check_pending(ssl) != 0) {
6340 MBEDTLS_SSL_DEBUG_MSG(1, ("There is pending incoming data"));
6341 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
Jarno Lamsa8c51b7c2019-08-21 13:45:05 +03006342 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006343 if (ssl->out_left != 0) {
6344 MBEDTLS_SSL_DEBUG_MSG(1, ("There is pending outgoing data"));
6345 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
Jarno Lamsa8c51b7c2019-08-21 13:45:05 +03006346 }
Dave Rodgmana03396a2022-12-06 16:30:38 +00006347 /* Protocol must be DTLS, not TLS */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006348 if (ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
6349 MBEDTLS_SSL_DEBUG_MSG(1, ("Only DTLS is supported"));
6350 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
Jarno Lamsa8c51b7c2019-08-21 13:45:05 +03006351 }
Manuel Pégourié-Gonnarde4588692019-07-29 12:28:52 +02006352 /* Version must be 1.2 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006353 if (ssl->major_ver != MBEDTLS_SSL_MAJOR_VERSION_3) {
6354 MBEDTLS_SSL_DEBUG_MSG(1, ("Only version 1.2 supported"));
6355 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
Jarno Lamsa8c51b7c2019-08-21 13:45:05 +03006356 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006357 if (ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_3) {
6358 MBEDTLS_SSL_DEBUG_MSG(1, ("Only version 1.2 supported"));
6359 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
Jarno Lamsa8c51b7c2019-08-21 13:45:05 +03006360 }
Manuel Pégourié-Gonnarde4588692019-07-29 12:28:52 +02006361 /* We must be using an AEAD ciphersuite */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006362 if (mbedtls_ssl_transform_uses_aead(ssl->transform) != 1) {
6363 MBEDTLS_SSL_DEBUG_MSG(1, ("Only AEAD ciphersuites supported"));
6364 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
Jarno Lamsa8c51b7c2019-08-21 13:45:05 +03006365 }
Manuel Pégourié-Gonnarde4588692019-07-29 12:28:52 +02006366 /* Renegotiation must not be enabled */
6367#if defined(MBEDTLS_SSL_RENEGOTIATION)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006368 if (ssl->conf->disable_renegotiation != MBEDTLS_SSL_RENEGOTIATION_DISABLED) {
6369 MBEDTLS_SSL_DEBUG_MSG(1, ("Renegotiation must not be enabled"));
6370 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
Jarno Lamsa8c51b7c2019-08-21 13:45:05 +03006371 }
Manuel Pégourié-Gonnarde4588692019-07-29 12:28:52 +02006372#endif
Manuel Pégourié-Gonnardac87e282019-05-28 13:02:16 +02006373
Manuel Pégourié-Gonnard4c90e852019-07-11 10:58:10 +02006374 /*
6375 * Version and format identifier
6376 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006377 used += sizeof(ssl_serialized_context_header);
Manuel Pégourié-Gonnardac87e282019-05-28 13:02:16 +02006378
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006379 if (used <= buf_len) {
6380 memcpy(p, ssl_serialized_context_header,
6381 sizeof(ssl_serialized_context_header));
6382 p += sizeof(ssl_serialized_context_header);
Manuel Pégourié-Gonnard4c90e852019-07-11 10:58:10 +02006383 }
6384
6385 /*
Manuel Pégourié-Gonnard4b7e6b92019-07-11 12:50:53 +02006386 * Session (length + data)
6387 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006388 ret = ssl_session_save(ssl->session, 1, NULL, 0, &session_len);
6389 if (ret != MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL) {
6390 return ret;
6391 }
Manuel Pégourié-Gonnard4b7e6b92019-07-11 12:50:53 +02006392
6393 used += 4 + session_len;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006394 if (used <= buf_len) {
6395 MBEDTLS_PUT_UINT32_BE(session_len, p, 0);
Joe Subbiani2f98d792021-08-20 11:44:44 +01006396 p += 4;
Manuel Pégourié-Gonnard4b7e6b92019-07-11 12:50:53 +02006397
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006398 ret = ssl_session_save(ssl->session, 1,
6399 p, session_len, &session_len);
6400 if (ret != 0) {
6401 return ret;
6402 }
Manuel Pégourié-Gonnard4b7e6b92019-07-11 12:50:53 +02006403
6404 p += session_len;
6405 }
6406
6407 /*
Manuel Pégourié-Gonnardc2a7b892019-07-15 09:04:11 +02006408 * Transform
6409 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006410 used += sizeof(ssl->transform->randbytes);
6411 if (used <= buf_len) {
6412 memcpy(p, ssl->transform->randbytes,
6413 sizeof(ssl->transform->randbytes));
6414 p += sizeof(ssl->transform->randbytes);
Manuel Pégourié-Gonnardc2a7b892019-07-15 09:04:11 +02006415 }
6416
6417#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
6418 used += 2 + ssl->transform->in_cid_len + ssl->transform->out_cid_len;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006419 if (used <= buf_len) {
Manuel Pégourié-Gonnardc2a7b892019-07-15 09:04:11 +02006420 *p++ = ssl->transform->in_cid_len;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006421 memcpy(p, ssl->transform->in_cid, ssl->transform->in_cid_len);
Manuel Pégourié-Gonnardc2a7b892019-07-15 09:04:11 +02006422 p += ssl->transform->in_cid_len;
6423
6424 *p++ = ssl->transform->out_cid_len;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006425 memcpy(p, ssl->transform->out_cid, ssl->transform->out_cid_len);
Manuel Pégourié-Gonnardc2a7b892019-07-15 09:04:11 +02006426 p += ssl->transform->out_cid_len;
6427 }
6428#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
6429
6430 /*
Manuel Pégourié-Gonnardc86c5df2019-07-15 11:23:03 +02006431 * Saved fields from top-level ssl_context structure
6432 */
6433#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT)
6434 used += 4;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006435 if (used <= buf_len) {
6436 MBEDTLS_PUT_UINT32_BE(ssl->badmac_seen, p, 0);
Joe Subbiani2f98d792021-08-20 11:44:44 +01006437 p += 4;
Manuel Pégourié-Gonnardc86c5df2019-07-15 11:23:03 +02006438 }
6439#endif /* MBEDTLS_SSL_DTLS_BADMAC_LIMIT */
6440
6441#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
6442 used += 16;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006443 if (used <= buf_len) {
6444 MBEDTLS_PUT_UINT64_BE(ssl->in_window_top, p, 0);
Joe Subbiani2f98d792021-08-20 11:44:44 +01006445 p += 8;
Manuel Pégourié-Gonnardc86c5df2019-07-15 11:23:03 +02006446
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006447 MBEDTLS_PUT_UINT64_BE(ssl->in_window, p, 0);
Joe Subbiani2f98d792021-08-20 11:44:44 +01006448 p += 8;
Manuel Pégourié-Gonnardc86c5df2019-07-15 11:23:03 +02006449 }
6450#endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */
6451
6452#if defined(MBEDTLS_SSL_PROTO_DTLS)
6453 used += 1;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006454 if (used <= buf_len) {
Manuel Pégourié-Gonnardc86c5df2019-07-15 11:23:03 +02006455 *p++ = ssl->disable_datagram_packing;
6456 }
6457#endif /* MBEDTLS_SSL_PROTO_DTLS */
6458
6459 used += 8;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006460 if (used <= buf_len) {
6461 memcpy(p, ssl->cur_out_ctr, 8);
Manuel Pégourié-Gonnardc86c5df2019-07-15 11:23:03 +02006462 p += 8;
6463 }
6464
6465#if defined(MBEDTLS_SSL_PROTO_DTLS)
6466 used += 2;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006467 if (used <= buf_len) {
6468 MBEDTLS_PUT_UINT16_BE(ssl->mtu, p, 0);
Joe Subbiani2f98d792021-08-20 11:44:44 +01006469 p += 2;
Manuel Pégourié-Gonnardc86c5df2019-07-15 11:23:03 +02006470 }
6471#endif /* MBEDTLS_SSL_PROTO_DTLS */
6472
6473#if defined(MBEDTLS_SSL_ALPN)
6474 {
6475 const uint8_t alpn_len = ssl->alpn_chosen
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006476 ? (uint8_t) strlen(ssl->alpn_chosen)
Manuel Pégourié-Gonnardc86c5df2019-07-15 11:23:03 +02006477 : 0;
6478
6479 used += 1 + alpn_len;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006480 if (used <= buf_len) {
Manuel Pégourié-Gonnardc86c5df2019-07-15 11:23:03 +02006481 *p++ = alpn_len;
6482
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006483 if (ssl->alpn_chosen != NULL) {
6484 memcpy(p, ssl->alpn_chosen, alpn_len);
Manuel Pégourié-Gonnardc86c5df2019-07-15 11:23:03 +02006485 p += alpn_len;
6486 }
6487 }
6488 }
6489#endif /* MBEDTLS_SSL_ALPN */
6490
6491 /*
Manuel Pégourié-Gonnard4c90e852019-07-11 10:58:10 +02006492 * Done
6493 */
6494 *olen = used;
6495
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006496 if (used > buf_len) {
6497 return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL;
6498 }
Manuel Pégourié-Gonnardac87e282019-05-28 13:02:16 +02006499
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006500 MBEDTLS_SSL_DEBUG_BUF(4, "saved context", buf, used);
Manuel Pégourié-Gonnard4b7e6b92019-07-11 12:50:53 +02006501
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006502 return mbedtls_ssl_session_reset_int(ssl, 0);
Manuel Pégourié-Gonnardac87e282019-05-28 13:02:16 +02006503}
6504
6505/*
Manuel Pégourié-Gonnardc2a7b892019-07-15 09:04:11 +02006506 * Helper to get TLS 1.2 PRF from ciphersuite
6507 * (Duplicates bits of logic from ssl_set_handshake_prfs().)
6508 */
Andrzej Kurekf9412f72022-10-18 07:30:19 -04006509#if defined(MBEDTLS_SHA256_C) || \
6510 (defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384))
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006511typedef int (*tls_prf_fn)(const unsigned char *secret, size_t slen,
6512 const char *label,
6513 const unsigned char *random, size_t rlen,
6514 unsigned char *dstbuf, size_t dlen);
6515static tls_prf_fn ssl_tls12prf_from_cs(int ciphersuite_id)
Manuel Pégourié-Gonnardc2a7b892019-07-15 09:04:11 +02006516{
6517 const mbedtls_ssl_ciphersuite_t * const ciphersuite_info =
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006518 mbedtls_ssl_ciphersuite_from_id(ciphersuite_id);
Manuel Pégourié-Gonnardc2a7b892019-07-15 09:04:11 +02006519
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006520 if (ciphersuite_info == NULL) {
6521 return NULL;
6522 }
Andrzej Kurek84fc52c2022-10-25 04:18:30 -04006523
6524#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006525 if (ciphersuite_info->mac == MBEDTLS_MD_SHA384) {
6526 return tls_prf_sha384;
6527 } else
Manuel Pégourié-Gonnard9a96fd72019-07-23 17:11:24 +02006528#endif
Andrzej Kurekf9412f72022-10-18 07:30:19 -04006529#if defined(MBEDTLS_SHA256_C)
6530 {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006531 if (ciphersuite_info->mac == MBEDTLS_MD_SHA256) {
6532 return tls_prf_sha256;
6533 }
Andrzej Kurekf9412f72022-10-18 07:30:19 -04006534 }
6535#endif
6536#if !defined(MBEDTLS_SHA256_C) && \
6537 (!defined(MBEDTLS_SHA512_C) || defined(MBEDTLS_SHA512_NO_SHA384))
6538 (void) ciphersuite_info;
6539#endif
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006540 return NULL;
Manuel Pégourié-Gonnardc2a7b892019-07-15 09:04:11 +02006541}
6542
Andrzej Kurekf9412f72022-10-18 07:30:19 -04006543#endif /* MBEDTLS_SHA256_C ||
6544 (MBEDTLS_SHA512_C && !MBEDTLS_SHA512_NO_SHA384) */
6545
Manuel Pégourié-Gonnardc2a7b892019-07-15 09:04:11 +02006546/*
Manuel Pégourié-Gonnardb9dfc9f2019-07-12 10:50:19 +02006547 * Deserialize context, see mbedtls_ssl_context_save() for format.
Manuel Pégourié-Gonnard4b7e6b92019-07-11 12:50:53 +02006548 *
6549 * This internal version is wrapped by a public function that cleans up in
6550 * case of error.
Manuel Pégourié-Gonnardac87e282019-05-28 13:02:16 +02006551 */
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +02006552MBEDTLS_CHECK_RETURN_CRITICAL
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006553static int ssl_context_load(mbedtls_ssl_context *ssl,
6554 const unsigned char *buf,
6555 size_t len)
Manuel Pégourié-Gonnardac87e282019-05-28 13:02:16 +02006556{
Manuel Pégourié-Gonnard4c90e852019-07-11 10:58:10 +02006557 const unsigned char *p = buf;
6558 const unsigned char * const end = buf + len;
Manuel Pégourié-Gonnard4b7e6b92019-07-11 12:50:53 +02006559 size_t session_len;
Janos Follath865b3eb2019-12-16 11:46:15 +00006560 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Andrzej Kurekf9412f72022-10-18 07:30:19 -04006561 tls_prf_fn prf_func = NULL;
Manuel Pégourié-Gonnard4c90e852019-07-11 10:58:10 +02006562
Manuel Pégourié-Gonnard0ff76402019-07-11 09:56:30 +02006563 /*
6564 * The context should have been freshly setup or reset.
6565 * Give the user an error in case of obvious misuse.
Manuel Pégourié-Gonnard4ca930f2019-07-26 16:31:53 +02006566 * (Checking session is useful because it won't be NULL if we're
Manuel Pégourié-Gonnard0ff76402019-07-11 09:56:30 +02006567 * renegotiating, or if the user mistakenly loaded a session first.)
6568 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006569 if (ssl->state != MBEDTLS_SSL_HELLO_REQUEST ||
6570 ssl->session != NULL) {
6571 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
Manuel Pégourié-Gonnard0ff76402019-07-11 09:56:30 +02006572 }
6573
6574 /*
6575 * We can't check that the config matches the initial one, but we can at
6576 * least check it matches the requirements for serializing.
6577 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006578 if (ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM ||
Manuel Pégourié-Gonnard0ff76402019-07-11 09:56:30 +02006579 ssl->conf->max_major_ver < MBEDTLS_SSL_MAJOR_VERSION_3 ||
6580 ssl->conf->min_major_ver > MBEDTLS_SSL_MAJOR_VERSION_3 ||
6581 ssl->conf->max_minor_ver < MBEDTLS_SSL_MINOR_VERSION_3 ||
6582 ssl->conf->min_minor_ver > MBEDTLS_SSL_MINOR_VERSION_3 ||
6583#if defined(MBEDTLS_SSL_RENEGOTIATION)
Manuel Pégourié-Gonnard9a96fd72019-07-23 17:11:24 +02006584 ssl->conf->disable_renegotiation != MBEDTLS_SSL_RENEGOTIATION_DISABLED ||
Manuel Pégourié-Gonnard0ff76402019-07-11 09:56:30 +02006585#endif
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006586 0) {
6587 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
Manuel Pégourié-Gonnard0ff76402019-07-11 09:56:30 +02006588 }
6589
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006590 MBEDTLS_SSL_DEBUG_BUF(4, "context to load", buf, len);
Manuel Pégourié-Gonnard4b7e6b92019-07-11 12:50:53 +02006591
Manuel Pégourié-Gonnard4c90e852019-07-11 10:58:10 +02006592 /*
6593 * Check version identifier
6594 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006595 if ((size_t) (end - p) < sizeof(ssl_serialized_context_header)) {
6596 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
Manuel Pégourié-Gonnard4c90e852019-07-11 10:58:10 +02006597 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006598
6599 if (memcmp(p, ssl_serialized_context_header,
6600 sizeof(ssl_serialized_context_header)) != 0) {
6601 return MBEDTLS_ERR_SSL_VERSION_MISMATCH;
6602 }
6603 p += sizeof(ssl_serialized_context_header);
Manuel Pégourié-Gonnard4c90e852019-07-11 10:58:10 +02006604
6605 /*
Manuel Pégourié-Gonnard4b7e6b92019-07-11 12:50:53 +02006606 * Session
6607 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006608 if ((size_t) (end - p) < 4) {
6609 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
6610 }
Manuel Pégourié-Gonnard4b7e6b92019-07-11 12:50:53 +02006611
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006612 session_len = ((size_t) p[0] << 24) |
6613 ((size_t) p[1] << 16) |
6614 ((size_t) p[2] << 8) |
6615 ((size_t) p[3]);
Manuel Pégourié-Gonnard4b7e6b92019-07-11 12:50:53 +02006616 p += 4;
6617
Manuel Pégourié-Gonnard142ba732019-07-23 14:43:30 +02006618 /* This has been allocated by ssl_handshake_init(), called by
Hanno Becker43aefe22020-02-05 10:44:56 +00006619 * by either mbedtls_ssl_session_reset_int() or mbedtls_ssl_setup(). */
Manuel Pégourié-Gonnard142ba732019-07-23 14:43:30 +02006620 ssl->session = ssl->session_negotiate;
Manuel Pégourié-Gonnard4b7e6b92019-07-11 12:50:53 +02006621 ssl->session_in = ssl->session;
6622 ssl->session_out = ssl->session;
Manuel Pégourié-Gonnard142ba732019-07-23 14:43:30 +02006623 ssl->session_negotiate = NULL;
Manuel Pégourié-Gonnard4b7e6b92019-07-11 12:50:53 +02006624
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006625 if ((size_t) (end - p) < session_len) {
6626 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
6627 }
Manuel Pégourié-Gonnard4b7e6b92019-07-11 12:50:53 +02006628
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006629 ret = ssl_session_load(ssl->session, 1, p, session_len);
6630 if (ret != 0) {
6631 mbedtls_ssl_session_free(ssl->session);
6632 return ret;
Manuel Pégourié-Gonnard45ac1f02019-07-23 16:52:45 +02006633 }
Manuel Pégourié-Gonnard4b7e6b92019-07-11 12:50:53 +02006634
6635 p += session_len;
6636
6637 /*
Manuel Pégourié-Gonnardc2a7b892019-07-15 09:04:11 +02006638 * Transform
6639 */
6640
Manuel Pégourié-Gonnard142ba732019-07-23 14:43:30 +02006641 /* This has been allocated by ssl_handshake_init(), called by
Hanno Becker43aefe22020-02-05 10:44:56 +00006642 * by either mbedtls_ssl_session_reset_int() or mbedtls_ssl_setup(). */
Manuel Pégourié-Gonnard142ba732019-07-23 14:43:30 +02006643 ssl->transform = ssl->transform_negotiate;
Manuel Pégourié-Gonnardc2a7b892019-07-15 09:04:11 +02006644 ssl->transform_in = ssl->transform;
6645 ssl->transform_out = ssl->transform;
Manuel Pégourié-Gonnard142ba732019-07-23 14:43:30 +02006646 ssl->transform_negotiate = NULL;
Manuel Pégourié-Gonnardc2a7b892019-07-15 09:04:11 +02006647
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006648 prf_func = ssl_tls12prf_from_cs(ssl->session->ciphersuite);
6649 if (prf_func == NULL) {
6650 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
6651 }
Andrzej Kurekf9412f72022-10-18 07:30:19 -04006652
Manuel Pégourié-Gonnardc2a7b892019-07-15 09:04:11 +02006653 /* Read random bytes and populate structure */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006654 if ((size_t) (end - p) < sizeof(ssl->transform->randbytes)) {
6655 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
6656 }
Manuel Pégourié-Gonnardc2a7b892019-07-15 09:04:11 +02006657
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006658 ret = ssl_populate_transform(ssl->transform,
6659 ssl->session->ciphersuite,
6660 ssl->session->master,
Manuel Pégourié-Gonnardc2a7b892019-07-15 09:04:11 +02006661#if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC)
6662#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006663 ssl->session->encrypt_then_mac,
Manuel Pégourié-Gonnardc2a7b892019-07-15 09:04:11 +02006664#endif
6665#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006666 ssl->session->trunc_hmac,
Manuel Pégourié-Gonnardc2a7b892019-07-15 09:04:11 +02006667#endif
6668#endif /* MBEDTLS_SSL_SOME_MODES_USE_MAC */
6669#if defined(MBEDTLS_ZLIB_SUPPORT)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006670 ssl->session->compression,
Manuel Pégourié-Gonnardc2a7b892019-07-15 09:04:11 +02006671#endif
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006672 prf_func,
6673 p, /* currently pointing to randbytes */
6674 MBEDTLS_SSL_MINOR_VERSION_3, /* (D)TLS 1.2 is forced */
6675 ssl->conf->endpoint,
6676 ssl);
6677 if (ret != 0) {
6678 return ret;
6679 }
Manuel Pégourié-Gonnardc2a7b892019-07-15 09:04:11 +02006680
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006681 p += sizeof(ssl->transform->randbytes);
Manuel Pégourié-Gonnardc2a7b892019-07-15 09:04:11 +02006682
6683#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
6684 /* Read connection IDs and store them */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006685 if ((size_t) (end - p) < 1) {
6686 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
6687 }
Manuel Pégourié-Gonnardc2a7b892019-07-15 09:04:11 +02006688
6689 ssl->transform->in_cid_len = *p++;
6690
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006691 if ((size_t) (end - p) < ssl->transform->in_cid_len + 1u) {
6692 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
6693 }
Manuel Pégourié-Gonnardc2a7b892019-07-15 09:04:11 +02006694
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006695 memcpy(ssl->transform->in_cid, p, ssl->transform->in_cid_len);
Manuel Pégourié-Gonnardc2a7b892019-07-15 09:04:11 +02006696 p += ssl->transform->in_cid_len;
6697
6698 ssl->transform->out_cid_len = *p++;
6699
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006700 if ((size_t) (end - p) < ssl->transform->out_cid_len) {
6701 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
6702 }
Manuel Pégourié-Gonnardc2a7b892019-07-15 09:04:11 +02006703
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006704 memcpy(ssl->transform->out_cid, p, ssl->transform->out_cid_len);
Manuel Pégourié-Gonnardc2a7b892019-07-15 09:04:11 +02006705 p += ssl->transform->out_cid_len;
6706#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
6707
6708 /*
Manuel Pégourié-Gonnardc86c5df2019-07-15 11:23:03 +02006709 * Saved fields from top-level ssl_context structure
6710 */
6711#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006712 if ((size_t) (end - p) < 4) {
6713 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
6714 }
Manuel Pégourié-Gonnardc86c5df2019-07-15 11:23:03 +02006715
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006716 ssl->badmac_seen = ((uint32_t) p[0] << 24) |
6717 ((uint32_t) p[1] << 16) |
6718 ((uint32_t) p[2] << 8) |
6719 ((uint32_t) p[3]);
Manuel Pégourié-Gonnardc86c5df2019-07-15 11:23:03 +02006720 p += 4;
6721#endif /* MBEDTLS_SSL_DTLS_BADMAC_LIMIT */
6722
6723#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006724 if ((size_t) (end - p) < 16) {
6725 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
6726 }
Manuel Pégourié-Gonnardc86c5df2019-07-15 11:23:03 +02006727
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006728 ssl->in_window_top = ((uint64_t) p[0] << 56) |
6729 ((uint64_t) p[1] << 48) |
6730 ((uint64_t) p[2] << 40) |
6731 ((uint64_t) p[3] << 32) |
6732 ((uint64_t) p[4] << 24) |
6733 ((uint64_t) p[5] << 16) |
6734 ((uint64_t) p[6] << 8) |
6735 ((uint64_t) p[7]);
Manuel Pégourié-Gonnardc86c5df2019-07-15 11:23:03 +02006736 p += 8;
6737
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006738 ssl->in_window = ((uint64_t) p[0] << 56) |
6739 ((uint64_t) p[1] << 48) |
6740 ((uint64_t) p[2] << 40) |
6741 ((uint64_t) p[3] << 32) |
6742 ((uint64_t) p[4] << 24) |
6743 ((uint64_t) p[5] << 16) |
6744 ((uint64_t) p[6] << 8) |
6745 ((uint64_t) p[7]);
Manuel Pégourié-Gonnardc86c5df2019-07-15 11:23:03 +02006746 p += 8;
6747#endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */
6748
6749#if defined(MBEDTLS_SSL_PROTO_DTLS)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006750 if ((size_t) (end - p) < 1) {
6751 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
6752 }
Manuel Pégourié-Gonnardc86c5df2019-07-15 11:23:03 +02006753
6754 ssl->disable_datagram_packing = *p++;
6755#endif /* MBEDTLS_SSL_PROTO_DTLS */
6756
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006757 if ((size_t) (end - p) < 8) {
6758 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
6759 }
Manuel Pégourié-Gonnardc86c5df2019-07-15 11:23:03 +02006760
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006761 memcpy(ssl->cur_out_ctr, p, 8);
Manuel Pégourié-Gonnardc86c5df2019-07-15 11:23:03 +02006762 p += 8;
6763
6764#if defined(MBEDTLS_SSL_PROTO_DTLS)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006765 if ((size_t) (end - p) < 2) {
6766 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
6767 }
Manuel Pégourié-Gonnardc86c5df2019-07-15 11:23:03 +02006768
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006769 ssl->mtu = (p[0] << 8) | p[1];
Manuel Pégourié-Gonnardc86c5df2019-07-15 11:23:03 +02006770 p += 2;
6771#endif /* MBEDTLS_SSL_PROTO_DTLS */
6772
6773#if defined(MBEDTLS_SSL_ALPN)
6774 {
6775 uint8_t alpn_len;
6776 const char **cur;
6777
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006778 if ((size_t) (end - p) < 1) {
6779 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
6780 }
Manuel Pégourié-Gonnardc86c5df2019-07-15 11:23:03 +02006781
6782 alpn_len = *p++;
6783
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006784 if (alpn_len != 0 && ssl->conf->alpn_list != NULL) {
Manuel Pégourié-Gonnardc86c5df2019-07-15 11:23:03 +02006785 /* alpn_chosen should point to an item in the configured list */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006786 for (cur = ssl->conf->alpn_list; *cur != NULL; cur++) {
6787 if (strlen(*cur) == alpn_len &&
Waleed Elmelegy98ebf482024-03-15 14:29:24 +00006788 memcmp(p, *cur, alpn_len) == 0) {
Manuel Pégourié-Gonnardc86c5df2019-07-15 11:23:03 +02006789 ssl->alpn_chosen = *cur;
6790 break;
6791 }
6792 }
6793 }
6794
6795 /* can only happen on conf mismatch */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006796 if (alpn_len != 0 && ssl->alpn_chosen == NULL) {
6797 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
6798 }
Manuel Pégourié-Gonnardc86c5df2019-07-15 11:23:03 +02006799
6800 p += alpn_len;
6801 }
6802#endif /* MBEDTLS_SSL_ALPN */
6803
6804 /*
Manuel Pégourié-Gonnard0eb3eac2019-07-15 11:53:51 +02006805 * Forced fields from top-level ssl_context structure
6806 *
6807 * Most of them already set to the correct value by mbedtls_ssl_init() and
6808 * mbedtls_ssl_reset(), so we only need to set the remaining ones.
6809 */
6810 ssl->state = MBEDTLS_SSL_HANDSHAKE_OVER;
6811
6812 ssl->major_ver = MBEDTLS_SSL_MAJOR_VERSION_3;
6813 ssl->minor_ver = MBEDTLS_SSL_MINOR_VERSION_3;
6814
Hanno Becker361b10d2019-08-30 10:42:49 +01006815 /* Adjust pointers for header fields of outgoing records to
6816 * the given transform, accounting for explicit IV and CID. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006817 mbedtls_ssl_update_out_pointers(ssl, ssl->transform);
Hanno Becker361b10d2019-08-30 10:42:49 +01006818
Manuel Pégourié-Gonnard0eb3eac2019-07-15 11:53:51 +02006819#if defined(MBEDTLS_SSL_PROTO_DTLS)
6820 ssl->in_epoch = 1;
6821#endif
6822
6823 /* mbedtls_ssl_reset() leaves the handshake sub-structure allocated,
6824 * which we don't want - otherwise we'd end up freeing the wrong transform
Hanno Beckerce5f5fd2020-02-05 10:47:44 +00006825 * by calling mbedtls_ssl_handshake_wrapup_free_hs_transform()
6826 * inappropriately. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006827 if (ssl->handshake != NULL) {
6828 mbedtls_ssl_handshake_free(ssl);
6829 mbedtls_free(ssl->handshake);
Manuel Pégourié-Gonnard0eb3eac2019-07-15 11:53:51 +02006830 ssl->handshake = NULL;
6831 }
6832
6833 /*
Manuel Pégourié-Gonnard4c90e852019-07-11 10:58:10 +02006834 * Done - should have consumed entire buffer
6835 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006836 if (p != end) {
6837 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
6838 }
Manuel Pégourié-Gonnardac87e282019-05-28 13:02:16 +02006839
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006840 return 0;
Manuel Pégourié-Gonnardac87e282019-05-28 13:02:16 +02006841}
6842
6843/*
Manuel Pégourié-Gonnardb9dfc9f2019-07-12 10:50:19 +02006844 * Deserialize context: public wrapper for error cleaning
Manuel Pégourié-Gonnard4b7e6b92019-07-11 12:50:53 +02006845 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006846int mbedtls_ssl_context_load(mbedtls_ssl_context *context,
6847 const unsigned char *buf,
6848 size_t len)
Manuel Pégourié-Gonnard4b7e6b92019-07-11 12:50:53 +02006849{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006850 int ret = ssl_context_load(context, buf, len);
Manuel Pégourié-Gonnard4b7e6b92019-07-11 12:50:53 +02006851
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006852 if (ret != 0) {
6853 mbedtls_ssl_free(context);
6854 }
Manuel Pégourié-Gonnard4b7e6b92019-07-11 12:50:53 +02006855
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006856 return ret;
Manuel Pégourié-Gonnard4b7e6b92019-07-11 12:50:53 +02006857}
Manuel Pégourié-Gonnard5c0e3772019-07-23 16:13:17 +02006858#endif /* MBEDTLS_SSL_CONTEXT_SERIALIZATION */
Manuel Pégourié-Gonnard4b7e6b92019-07-11 12:50:53 +02006859
6860/*
Paul Bakker5121ce52009-01-03 21:22:43 +00006861 * Free an SSL context
6862 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006863void mbedtls_ssl_free(mbedtls_ssl_context *ssl)
Paul Bakker5121ce52009-01-03 21:22:43 +00006864{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006865 if (ssl == NULL) {
Paul Bakkeraccaffe2014-06-26 13:37:14 +02006866 return;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006867 }
Paul Bakkeraccaffe2014-06-26 13:37:14 +02006868
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006869 MBEDTLS_SSL_DEBUG_MSG(2, ("=> free"));
Paul Bakker5121ce52009-01-03 21:22:43 +00006870
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006871 if (ssl->out_buf != NULL) {
sander-visserb8aa2072020-05-06 22:05:13 +02006872#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
6873 size_t out_buf_len = ssl->out_buf_len;
6874#else
6875 size_t out_buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN;
6876#endif
6877
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006878 mbedtls_platform_zeroize(ssl->out_buf, out_buf_len);
6879 mbedtls_free(ssl->out_buf);
Andrzej Kurek0afa2a12020-03-03 10:39:58 -05006880 ssl->out_buf = NULL;
Paul Bakker5121ce52009-01-03 21:22:43 +00006881 }
6882
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006883 if (ssl->in_buf != NULL) {
sander-visserb8aa2072020-05-06 22:05:13 +02006884#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
6885 size_t in_buf_len = ssl->in_buf_len;
6886#else
6887 size_t in_buf_len = MBEDTLS_SSL_IN_BUFFER_LEN;
6888#endif
6889
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006890 mbedtls_platform_zeroize(ssl->in_buf, in_buf_len);
6891 mbedtls_free(ssl->in_buf);
Andrzej Kurek0afa2a12020-03-03 10:39:58 -05006892 ssl->in_buf = NULL;
Paul Bakker5121ce52009-01-03 21:22:43 +00006893 }
6894
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02006895#if defined(MBEDTLS_ZLIB_SUPPORT)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006896 if (ssl->compress_buf != NULL) {
6897 mbedtls_platform_zeroize(ssl->compress_buf, MBEDTLS_SSL_COMPRESS_BUFFER_LEN);
6898 mbedtls_free(ssl->compress_buf);
Paul Bakker16770332013-10-11 09:59:44 +02006899 }
6900#endif
6901
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006902 if (ssl->transform) {
6903 mbedtls_ssl_transform_free(ssl->transform);
6904 mbedtls_free(ssl->transform);
Paul Bakker48916f92012-09-16 19:57:18 +00006905 }
6906
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006907 if (ssl->handshake) {
6908 mbedtls_ssl_handshake_free(ssl);
6909 mbedtls_ssl_transform_free(ssl->transform_negotiate);
6910 mbedtls_ssl_session_free(ssl->session_negotiate);
Paul Bakker48916f92012-09-16 19:57:18 +00006911
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006912 mbedtls_free(ssl->handshake);
6913 mbedtls_free(ssl->transform_negotiate);
6914 mbedtls_free(ssl->session_negotiate);
Paul Bakker48916f92012-09-16 19:57:18 +00006915 }
6916
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006917 if (ssl->session) {
6918 mbedtls_ssl_session_free(ssl->session);
6919 mbedtls_free(ssl->session);
Paul Bakkerc0463502013-02-14 11:19:38 +01006920 }
6921
Manuel Pégourié-Gonnard55fab2d2015-05-11 16:15:19 +02006922#if defined(MBEDTLS_X509_CRT_PARSE_C)
Gilles Peskine3a2f75d2025-02-12 23:28:48 +01006923 mbedtls_ssl_free_hostname(ssl);
Paul Bakker0be444a2013-08-27 21:55:01 +02006924#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00006925
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02006926#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006927 if (mbedtls_ssl_hw_record_finish != NULL) {
6928 MBEDTLS_SSL_DEBUG_MSG(2, ("going for mbedtls_ssl_hw_record_finish()"));
6929 mbedtls_ssl_hw_record_finish(ssl);
Paul Bakker05ef8352012-05-08 09:17:57 +00006930 }
6931#endif
6932
Manuel Pégourié-Gonnarde057d3b2015-05-20 10:59:43 +02006933#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006934 mbedtls_free(ssl->cli_id);
Manuel Pégourié-Gonnard43c02182014-07-22 17:32:01 +02006935#endif
6936
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006937 MBEDTLS_SSL_DEBUG_MSG(2, ("<= free"));
Paul Bakker2da561c2009-02-05 18:00:28 +00006938
Paul Bakker86f04f42013-02-14 11:20:09 +01006939 /* Actually clear after last debug message */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006940 mbedtls_platform_zeroize(ssl, sizeof(mbedtls_ssl_context));
Paul Bakker5121ce52009-01-03 21:22:43 +00006941}
6942
Manuel Pégourié-Gonnardcd523e22015-05-04 13:35:39 +02006943/*
Tom Cosgrove49f99bc2022-12-04 16:44:21 +00006944 * Initialize mbedtls_ssl_config
Manuel Pégourié-Gonnardcd523e22015-05-04 13:35:39 +02006945 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006946void mbedtls_ssl_config_init(mbedtls_ssl_config *conf)
Manuel Pégourié-Gonnardcd523e22015-05-04 13:35:39 +02006947{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006948 memset(conf, 0, sizeof(mbedtls_ssl_config));
Manuel Pégourié-Gonnardcd523e22015-05-04 13:35:39 +02006949}
6950
Gilles Peskineeccd8882020-03-10 12:19:08 +01006951#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
Chien Wongb6d57932024-02-07 21:48:12 +08006952static const int ssl_preset_default_hashes[] = {
Gilles Peskinec54010c2021-05-12 22:52:09 +02006953#if defined(MBEDTLS_SHA512_C)
Manuel Pégourié-Gonnard47229c72015-12-04 15:02:56 +01006954 MBEDTLS_MD_SHA512,
Gilles Peskinec54010c2021-05-12 22:52:09 +02006955#endif
6956#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384)
Manuel Pégourié-Gonnard47229c72015-12-04 15:02:56 +01006957 MBEDTLS_MD_SHA384,
6958#endif
6959#if defined(MBEDTLS_SHA256_C)
6960 MBEDTLS_MD_SHA256,
6961 MBEDTLS_MD_SHA224,
6962#endif
Gilles Peskine5d2511c2017-05-12 13:16:40 +02006963#if defined(MBEDTLS_SHA1_C) && defined(MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_KEY_EXCHANGE)
Manuel Pégourié-Gonnard47229c72015-12-04 15:02:56 +01006964 MBEDTLS_MD_SHA1,
6965#endif
6966 MBEDTLS_MD_NONE
6967};
Simon Butcherc97b6972015-12-27 23:48:17 +00006968#endif
Manuel Pégourié-Gonnard47229c72015-12-04 15:02:56 +01006969
Chien Wongb6d57932024-02-07 21:48:12 +08006970static const int ssl_preset_suiteb_ciphersuites[] = {
Manuel Pégourié-Gonnardb31c5f62015-06-17 13:53:47 +02006971 MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
6972 MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
6973 0
6974};
6975
Gilles Peskineeccd8882020-03-10 12:19:08 +01006976#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
Chien Wongb6d57932024-02-07 21:48:12 +08006977static const int ssl_preset_suiteb_hashes[] = {
Manuel Pégourié-Gonnardb31c5f62015-06-17 13:53:47 +02006978 MBEDTLS_MD_SHA256,
6979 MBEDTLS_MD_SHA384,
6980 MBEDTLS_MD_NONE
6981};
6982#endif
6983
6984#if defined(MBEDTLS_ECP_C)
Chien Wongb6d57932024-02-07 21:48:12 +08006985static const mbedtls_ecp_group_id ssl_preset_suiteb_curves[] = {
Jaeden Amerod4311042019-06-03 08:27:16 +01006986#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
Manuel Pégourié-Gonnardb31c5f62015-06-17 13:53:47 +02006987 MBEDTLS_ECP_DP_SECP256R1,
Jaeden Amerod4311042019-06-03 08:27:16 +01006988#endif
6989#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
Manuel Pégourié-Gonnardb31c5f62015-06-17 13:53:47 +02006990 MBEDTLS_ECP_DP_SECP384R1,
Jaeden Amerod4311042019-06-03 08:27:16 +01006991#endif
Manuel Pégourié-Gonnardb31c5f62015-06-17 13:53:47 +02006992 MBEDTLS_ECP_DP_NONE
6993};
6994#endif
6995
Manuel Pégourié-Gonnardcd523e22015-05-04 13:35:39 +02006996/*
Tillmann Karras588ad502015-09-25 04:27:22 +02006997 * Load default in mbedtls_ssl_config
Manuel Pégourié-Gonnardcd523e22015-05-04 13:35:39 +02006998 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006999int mbedtls_ssl_config_defaults(mbedtls_ssl_config *conf,
7000 int endpoint, int transport, int preset)
Manuel Pégourié-Gonnardcd523e22015-05-04 13:35:39 +02007001{
Manuel Pégourié-Gonnard8b431fb2015-05-11 12:54:52 +02007002#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_SRV_C)
Janos Follath865b3eb2019-12-16 11:46:15 +00007003 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard8b431fb2015-05-11 12:54:52 +02007004#endif
Manuel Pégourié-Gonnardcd523e22015-05-04 13:35:39 +02007005
Manuel Pégourié-Gonnard0de074f2015-05-14 12:58:01 +02007006 /* Use the functions here so that they are covered in tests,
7007 * but otherwise access member directly for efficiency */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007008 mbedtls_ssl_conf_endpoint(conf, endpoint);
7009 mbedtls_ssl_conf_transport(conf, transport);
Manuel Pégourié-Gonnardcd523e22015-05-04 13:35:39 +02007010
Manuel Pégourié-Gonnardb31c5f62015-06-17 13:53:47 +02007011 /*
7012 * Things that are common to all presets
7013 */
Manuel Pégourié-Gonnard419d5ae2015-05-04 19:32:36 +02007014#if defined(MBEDTLS_SSL_CLI_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007015 if (endpoint == MBEDTLS_SSL_IS_CLIENT) {
Manuel Pégourié-Gonnard419d5ae2015-05-04 19:32:36 +02007016 conf->authmode = MBEDTLS_SSL_VERIFY_REQUIRED;
7017#if defined(MBEDTLS_SSL_SESSION_TICKETS)
7018 conf->session_tickets = MBEDTLS_SSL_SESSION_TICKETS_ENABLED;
7019#endif
7020 }
7021#endif
7022
Manuel Pégourié-Gonnard66dc5552015-05-14 12:28:21 +02007023#if defined(MBEDTLS_ARC4_C)
Manuel Pégourié-Gonnardcd523e22015-05-04 13:35:39 +02007024 conf->arc4_disabled = MBEDTLS_SSL_ARC4_DISABLED;
Manuel Pégourié-Gonnard66dc5552015-05-14 12:28:21 +02007025#endif
Manuel Pégourié-Gonnardcd523e22015-05-04 13:35:39 +02007026
7027#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
7028 conf->encrypt_then_mac = MBEDTLS_SSL_ETM_ENABLED;
7029#endif
7030
7031#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
7032 conf->extended_ms = MBEDTLS_SSL_EXTENDED_MS_ENABLED;
7033#endif
7034
Manuel Pégourié-Gonnard17eab2b2015-05-05 16:34:53 +01007035#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING)
7036 conf->cbc_record_splitting = MBEDTLS_SSL_CBC_RECORD_SPLITTING_ENABLED;
7037#endif
7038
Manuel Pégourié-Gonnarde057d3b2015-05-20 10:59:43 +02007039#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C)
Manuel Pégourié-Gonnardcd523e22015-05-04 13:35:39 +02007040 conf->f_cookie_write = ssl_cookie_write_dummy;
7041 conf->f_cookie_check = ssl_cookie_check_dummy;
7042#endif
7043
7044#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
7045 conf->anti_replay = MBEDTLS_SSL_ANTI_REPLAY_ENABLED;
7046#endif
7047
Janos Follath088ce432017-04-10 12:42:31 +01007048#if defined(MBEDTLS_SSL_SRV_C)
7049 conf->cert_req_ca_list = MBEDTLS_SSL_CERT_REQ_CA_LIST_ENABLED;
7050#endif
7051
Manuel Pégourié-Gonnardcd523e22015-05-04 13:35:39 +02007052#if defined(MBEDTLS_SSL_PROTO_DTLS)
7053 conf->hs_timeout_min = MBEDTLS_SSL_DTLS_TIMEOUT_DFL_MIN;
7054 conf->hs_timeout_max = MBEDTLS_SSL_DTLS_TIMEOUT_DFL_MAX;
7055#endif
7056
7057#if defined(MBEDTLS_SSL_RENEGOTIATION)
7058 conf->renego_max_records = MBEDTLS_SSL_RENEGO_MAX_RECORDS_DEFAULT;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007059 memset(conf->renego_period, 0x00, 2);
7060 memset(conf->renego_period + 2, 0xFF, 6);
Manuel Pégourié-Gonnardcd523e22015-05-04 13:35:39 +02007061#endif
7062
Manuel Pégourié-Gonnardb31c5f62015-06-17 13:53:47 +02007063#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_SRV_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007064 if (endpoint == MBEDTLS_SSL_IS_SERVER) {
7065 const unsigned char dhm_p[] =
7066 MBEDTLS_DHM_RFC3526_MODP_2048_P_BIN;
7067 const unsigned char dhm_g[] =
7068 MBEDTLS_DHM_RFC3526_MODP_2048_G_BIN;
Hanno Becker00d0a682017-10-04 13:14:29 +01007069
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007070 if ((ret = mbedtls_ssl_conf_dh_param_bin(conf,
7071 dhm_p, sizeof(dhm_p),
7072 dhm_g, sizeof(dhm_g))) != 0) {
7073 return ret;
7074 }
7075 }
Manuel Pégourié-Gonnardbd990d62015-06-11 14:49:42 +02007076#endif
7077
Manuel Pégourié-Gonnardb31c5f62015-06-17 13:53:47 +02007078 /*
7079 * Preset-specific defaults
7080 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007081 switch (preset) {
Manuel Pégourié-Gonnardb31c5f62015-06-17 13:53:47 +02007082 /*
7083 * NSA Suite B
7084 */
7085 case MBEDTLS_SSL_PRESET_SUITEB:
7086 conf->min_major_ver = MBEDTLS_SSL_MAJOR_VERSION_3;
7087 conf->min_minor_ver = MBEDTLS_SSL_MINOR_VERSION_3; /* TLS 1.2 */
7088 conf->max_major_ver = MBEDTLS_SSL_MAX_MAJOR_VERSION;
7089 conf->max_minor_ver = MBEDTLS_SSL_MAX_MINOR_VERSION;
7090
7091 conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_0] =
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007092 conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_1] =
7093 conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_2] =
7094 conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_3] =
7095 ssl_preset_suiteb_ciphersuites;
Manuel Pégourié-Gonnardb31c5f62015-06-17 13:53:47 +02007096
7097#if defined(MBEDTLS_X509_CRT_PARSE_C)
7098 conf->cert_profile = &mbedtls_x509_crt_profile_suiteb;
Manuel Pégourié-Gonnardcd523e22015-05-04 13:35:39 +02007099#endif
7100
Gilles Peskineeccd8882020-03-10 12:19:08 +01007101#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
Manuel Pégourié-Gonnardb31c5f62015-06-17 13:53:47 +02007102 conf->sig_hashes = ssl_preset_suiteb_hashes;
7103#endif
7104
7105#if defined(MBEDTLS_ECP_C)
7106 conf->curve_list = ssl_preset_suiteb_curves;
7107#endif
Manuel Pégourié-Gonnardc98204e2015-08-11 04:21:01 +02007108 break;
Manuel Pégourié-Gonnardb31c5f62015-06-17 13:53:47 +02007109
7110 /*
7111 * Default
7112 */
7113 default:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007114 conf->min_major_ver = (MBEDTLS_SSL_MIN_MAJOR_VERSION >
7115 MBEDTLS_SSL_MIN_VALID_MAJOR_VERSION) ?
7116 MBEDTLS_SSL_MIN_MAJOR_VERSION :
7117 MBEDTLS_SSL_MIN_VALID_MAJOR_VERSION;
7118 conf->min_minor_ver = (MBEDTLS_SSL_MIN_MINOR_VERSION >
7119 MBEDTLS_SSL_MIN_VALID_MINOR_VERSION) ?
7120 MBEDTLS_SSL_MIN_MINOR_VERSION :
7121 MBEDTLS_SSL_MIN_VALID_MINOR_VERSION;
Manuel Pégourié-Gonnardb31c5f62015-06-17 13:53:47 +02007122 conf->max_major_ver = MBEDTLS_SSL_MAX_MAJOR_VERSION;
7123 conf->max_minor_ver = MBEDTLS_SSL_MAX_MINOR_VERSION;
7124
7125#if defined(MBEDTLS_SSL_PROTO_DTLS)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007126 if (transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
Manuel Pégourié-Gonnardb31c5f62015-06-17 13:53:47 +02007127 conf->min_minor_ver = MBEDTLS_SSL_MINOR_VERSION_2;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007128 }
Manuel Pégourié-Gonnardb31c5f62015-06-17 13:53:47 +02007129#endif
7130
7131 conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_0] =
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007132 conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_1] =
7133 conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_2] =
7134 conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_3] =
7135 mbedtls_ssl_list_ciphersuites();
Manuel Pégourié-Gonnardb31c5f62015-06-17 13:53:47 +02007136
7137#if defined(MBEDTLS_X509_CRT_PARSE_C)
7138 conf->cert_profile = &mbedtls_x509_crt_profile_default;
7139#endif
7140
Gilles Peskineeccd8882020-03-10 12:19:08 +01007141#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
Manuel Pégourié-Gonnard47229c72015-12-04 15:02:56 +01007142 conf->sig_hashes = ssl_preset_default_hashes;
Manuel Pégourié-Gonnardb31c5f62015-06-17 13:53:47 +02007143#endif
7144
7145#if defined(MBEDTLS_ECP_C)
7146 conf->curve_list = mbedtls_ecp_grp_id_list();
7147#endif
7148
7149#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_CLI_C)
7150 conf->dhm_min_bitlen = 1024;
7151#endif
7152 }
7153
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007154 return 0;
Manuel Pégourié-Gonnardcd523e22015-05-04 13:35:39 +02007155}
7156
7157/*
7158 * Free mbedtls_ssl_config
7159 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007160void mbedtls_ssl_config_free(mbedtls_ssl_config *conf)
Manuel Pégourié-Gonnardcd523e22015-05-04 13:35:39 +02007161{
7162#if defined(MBEDTLS_DHM_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007163 mbedtls_mpi_free(&conf->dhm_P);
7164 mbedtls_mpi_free(&conf->dhm_G);
Manuel Pégourié-Gonnardcd523e22015-05-04 13:35:39 +02007165#endif
7166
Gilles Peskineeccd8882020-03-10 12:19:08 +01007167#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007168 if (conf->psk != NULL) {
7169 mbedtls_platform_zeroize(conf->psk, conf->psk_len);
7170 mbedtls_free(conf->psk);
Azim Khan27e8a122018-03-21 14:24:11 +00007171 conf->psk = NULL;
Manuel Pégourié-Gonnardcd523e22015-05-04 13:35:39 +02007172 conf->psk_len = 0;
junyeonLEE316b1622017-12-20 16:29:30 +09007173 }
7174
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007175 if (conf->psk_identity != NULL) {
7176 mbedtls_platform_zeroize(conf->psk_identity, conf->psk_identity_len);
7177 mbedtls_free(conf->psk_identity);
Azim Khan27e8a122018-03-21 14:24:11 +00007178 conf->psk_identity = NULL;
Manuel Pégourié-Gonnardcd523e22015-05-04 13:35:39 +02007179 conf->psk_identity_len = 0;
7180 }
7181#endif
7182
7183#if defined(MBEDTLS_X509_CRT_PARSE_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007184 ssl_key_cert_free(conf->key_cert);
Manuel Pégourié-Gonnardcd523e22015-05-04 13:35:39 +02007185#endif
7186
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007187 mbedtls_platform_zeroize(conf, sizeof(mbedtls_ssl_config));
Manuel Pégourié-Gonnardcd523e22015-05-04 13:35:39 +02007188}
7189
Manuel Pégourié-Gonnard5674a972015-10-19 15:14:03 +02007190#if defined(MBEDTLS_PK_C) && \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007191 (defined(MBEDTLS_RSA_C) || defined(MBEDTLS_ECDSA_C))
Manuel Pégourié-Gonnard0d420492013-08-21 16:14:26 +02007192/*
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02007193 * Convert between MBEDTLS_PK_XXX and SSL_SIG_XXX
Manuel Pégourié-Gonnard0d420492013-08-21 16:14:26 +02007194 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007195unsigned char mbedtls_ssl_sig_from_pk(mbedtls_pk_context *pk)
Manuel Pégourié-Gonnard0d420492013-08-21 16:14:26 +02007196{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02007197#if defined(MBEDTLS_RSA_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007198 if (mbedtls_pk_can_do(pk, MBEDTLS_PK_RSA)) {
7199 return MBEDTLS_SSL_SIG_RSA;
7200 }
Manuel Pégourié-Gonnard0d420492013-08-21 16:14:26 +02007201#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02007202#if defined(MBEDTLS_ECDSA_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007203 if (mbedtls_pk_can_do(pk, MBEDTLS_PK_ECDSA)) {
7204 return MBEDTLS_SSL_SIG_ECDSA;
7205 }
Manuel Pégourié-Gonnard0d420492013-08-21 16:14:26 +02007206#endif
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007207 return MBEDTLS_SSL_SIG_ANON;
Manuel Pégourié-Gonnard0d420492013-08-21 16:14:26 +02007208}
7209
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007210unsigned char mbedtls_ssl_sig_from_pk_alg(mbedtls_pk_type_t type)
Hanno Becker7e5437a2017-04-28 17:15:26 +01007211{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007212 switch (type) {
Hanno Becker7e5437a2017-04-28 17:15:26 +01007213 case MBEDTLS_PK_RSA:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007214 return MBEDTLS_SSL_SIG_RSA;
Hanno Becker7e5437a2017-04-28 17:15:26 +01007215 case MBEDTLS_PK_ECDSA:
7216 case MBEDTLS_PK_ECKEY:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007217 return MBEDTLS_SSL_SIG_ECDSA;
Hanno Becker7e5437a2017-04-28 17:15:26 +01007218 default:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007219 return MBEDTLS_SSL_SIG_ANON;
Hanno Becker7e5437a2017-04-28 17:15:26 +01007220 }
7221}
7222
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007223mbedtls_pk_type_t mbedtls_ssl_pk_alg_from_sig(unsigned char sig)
Manuel Pégourié-Gonnarda20c58c2013-08-22 13:52:48 +02007224{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007225 switch (sig) {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02007226#if defined(MBEDTLS_RSA_C)
7227 case MBEDTLS_SSL_SIG_RSA:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007228 return MBEDTLS_PK_RSA;
Manuel Pégourié-Gonnarda20c58c2013-08-22 13:52:48 +02007229#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02007230#if defined(MBEDTLS_ECDSA_C)
7231 case MBEDTLS_SSL_SIG_ECDSA:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007232 return MBEDTLS_PK_ECDSA;
Manuel Pégourié-Gonnarda20c58c2013-08-22 13:52:48 +02007233#endif
7234 default:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007235 return MBEDTLS_PK_NONE;
Manuel Pégourié-Gonnarda20c58c2013-08-22 13:52:48 +02007236 }
7237}
Manuel Pégourié-Gonnard5674a972015-10-19 15:14:03 +02007238#endif /* MBEDTLS_PK_C && ( MBEDTLS_RSA_C || MBEDTLS_ECDSA_C ) */
Manuel Pégourié-Gonnarda20c58c2013-08-22 13:52:48 +02007239
Hanno Becker7e5437a2017-04-28 17:15:26 +01007240#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
Gilles Peskineeccd8882020-03-10 12:19:08 +01007241 defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
Hanno Becker7e5437a2017-04-28 17:15:26 +01007242
7243/* Find an entry in a signature-hash set matching a given hash algorithm. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007244mbedtls_md_type_t mbedtls_ssl_sig_hash_set_find(mbedtls_ssl_sig_hash_set_t *set,
7245 mbedtls_pk_type_t sig_alg)
Hanno Becker7e5437a2017-04-28 17:15:26 +01007246{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007247 switch (sig_alg) {
Hanno Becker7e5437a2017-04-28 17:15:26 +01007248 case MBEDTLS_PK_RSA:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007249 return set->rsa;
Hanno Becker7e5437a2017-04-28 17:15:26 +01007250 case MBEDTLS_PK_ECDSA:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007251 return set->ecdsa;
Hanno Becker7e5437a2017-04-28 17:15:26 +01007252 default:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007253 return MBEDTLS_MD_NONE;
Hanno Becker7e5437a2017-04-28 17:15:26 +01007254 }
7255}
7256
7257/* Add a signature-hash-pair to a signature-hash set */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007258void mbedtls_ssl_sig_hash_set_add(mbedtls_ssl_sig_hash_set_t *set,
7259 mbedtls_pk_type_t sig_alg,
7260 mbedtls_md_type_t md_alg)
Hanno Becker7e5437a2017-04-28 17:15:26 +01007261{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007262 switch (sig_alg) {
Hanno Becker7e5437a2017-04-28 17:15:26 +01007263 case MBEDTLS_PK_RSA:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007264 if (set->rsa == MBEDTLS_MD_NONE) {
Hanno Becker7e5437a2017-04-28 17:15:26 +01007265 set->rsa = md_alg;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007266 }
Hanno Becker7e5437a2017-04-28 17:15:26 +01007267 break;
7268
7269 case MBEDTLS_PK_ECDSA:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007270 if (set->ecdsa == MBEDTLS_MD_NONE) {
Hanno Becker7e5437a2017-04-28 17:15:26 +01007271 set->ecdsa = md_alg;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007272 }
Hanno Becker7e5437a2017-04-28 17:15:26 +01007273 break;
7274
7275 default:
7276 break;
7277 }
7278}
7279
7280/* Allow exactly one hash algorithm for each signature. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007281void mbedtls_ssl_sig_hash_set_const_hash(mbedtls_ssl_sig_hash_set_t *set,
7282 mbedtls_md_type_t md_alg)
Hanno Becker7e5437a2017-04-28 17:15:26 +01007283{
7284 set->rsa = md_alg;
7285 set->ecdsa = md_alg;
7286}
7287
7288#endif /* MBEDTLS_SSL_PROTO_TLS1_2) &&
Gilles Peskineeccd8882020-03-10 12:19:08 +01007289 MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
Hanno Becker7e5437a2017-04-28 17:15:26 +01007290
Manuel Pégourié-Gonnard1a483832013-09-20 12:29:15 +02007291/*
Manuel Pégourié-Gonnard7bfc1222015-06-17 14:34:48 +02007292 * Convert from MBEDTLS_SSL_HASH_XXX to MBEDTLS_MD_XXX
Manuel Pégourié-Gonnard1a483832013-09-20 12:29:15 +02007293 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007294mbedtls_md_type_t mbedtls_ssl_md_alg_from_hash(unsigned char hash)
Manuel Pégourié-Gonnarda20c58c2013-08-22 13:52:48 +02007295{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007296 switch (hash) {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02007297#if defined(MBEDTLS_MD5_C)
7298 case MBEDTLS_SSL_HASH_MD5:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007299 return MBEDTLS_MD_MD5;
Manuel Pégourié-Gonnarda20c58c2013-08-22 13:52:48 +02007300#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02007301#if defined(MBEDTLS_SHA1_C)
7302 case MBEDTLS_SSL_HASH_SHA1:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007303 return MBEDTLS_MD_SHA1;
Manuel Pégourié-Gonnarda20c58c2013-08-22 13:52:48 +02007304#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02007305#if defined(MBEDTLS_SHA256_C)
7306 case MBEDTLS_SSL_HASH_SHA224:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007307 return MBEDTLS_MD_SHA224;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02007308 case MBEDTLS_SSL_HASH_SHA256:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007309 return MBEDTLS_MD_SHA256;
Manuel Pégourié-Gonnarda20c58c2013-08-22 13:52:48 +02007310#endif
Gilles Peskined2d59372021-05-12 22:43:27 +02007311#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02007312 case MBEDTLS_SSL_HASH_SHA384:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007313 return MBEDTLS_MD_SHA384;
Gilles Peskinec54010c2021-05-12 22:52:09 +02007314#endif
7315#if defined(MBEDTLS_SHA512_C)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02007316 case MBEDTLS_SSL_HASH_SHA512:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007317 return MBEDTLS_MD_SHA512;
Manuel Pégourié-Gonnarda20c58c2013-08-22 13:52:48 +02007318#endif
7319 default:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007320 return MBEDTLS_MD_NONE;
Manuel Pégourié-Gonnarda20c58c2013-08-22 13:52:48 +02007321 }
7322}
7323
Manuel Pégourié-Gonnard7bfc1222015-06-17 14:34:48 +02007324/*
7325 * Convert from MBEDTLS_MD_XXX to MBEDTLS_SSL_HASH_XXX
7326 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007327unsigned char mbedtls_ssl_hash_from_md_alg(int md)
Manuel Pégourié-Gonnard7bfc1222015-06-17 14:34:48 +02007328{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007329 switch (md) {
Manuel Pégourié-Gonnard7bfc1222015-06-17 14:34:48 +02007330#if defined(MBEDTLS_MD5_C)
7331 case MBEDTLS_MD_MD5:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007332 return MBEDTLS_SSL_HASH_MD5;
Manuel Pégourié-Gonnard7bfc1222015-06-17 14:34:48 +02007333#endif
7334#if defined(MBEDTLS_SHA1_C)
7335 case MBEDTLS_MD_SHA1:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007336 return MBEDTLS_SSL_HASH_SHA1;
Manuel Pégourié-Gonnard7bfc1222015-06-17 14:34:48 +02007337#endif
7338#if defined(MBEDTLS_SHA256_C)
7339 case MBEDTLS_MD_SHA224:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007340 return MBEDTLS_SSL_HASH_SHA224;
Manuel Pégourié-Gonnard7bfc1222015-06-17 14:34:48 +02007341 case MBEDTLS_MD_SHA256:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007342 return MBEDTLS_SSL_HASH_SHA256;
Manuel Pégourié-Gonnard7bfc1222015-06-17 14:34:48 +02007343#endif
Gilles Peskined2d59372021-05-12 22:43:27 +02007344#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384)
Manuel Pégourié-Gonnard7bfc1222015-06-17 14:34:48 +02007345 case MBEDTLS_MD_SHA384:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007346 return MBEDTLS_SSL_HASH_SHA384;
Gilles Peskinec54010c2021-05-12 22:52:09 +02007347#endif
7348#if defined(MBEDTLS_SHA512_C)
Manuel Pégourié-Gonnard7bfc1222015-06-17 14:34:48 +02007349 case MBEDTLS_MD_SHA512:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007350 return MBEDTLS_SSL_HASH_SHA512;
Manuel Pégourié-Gonnard7bfc1222015-06-17 14:34:48 +02007351#endif
7352 default:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007353 return MBEDTLS_SSL_HASH_NONE;
Manuel Pégourié-Gonnard7bfc1222015-06-17 14:34:48 +02007354 }
7355}
7356
Manuel Pégourié-Gonnardb541da62015-06-17 11:43:30 +02007357#if defined(MBEDTLS_ECP_C)
Manuel Pégourié-Gonnardab240102014-02-04 16:18:07 +01007358/*
Manuel Pégourié-Gonnard7bfc1222015-06-17 14:34:48 +02007359 * Check if a curve proposed by the peer is in our list.
Manuel Pégourié-Gonnard9d412d82015-06-17 12:10:46 +02007360 * Return 0 if we're willing to use it, -1 otherwise.
Manuel Pégourié-Gonnardab240102014-02-04 16:18:07 +01007361 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007362int mbedtls_ssl_check_curve(const mbedtls_ssl_context *ssl, mbedtls_ecp_group_id grp_id)
Manuel Pégourié-Gonnardab240102014-02-04 16:18:07 +01007363{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02007364 const mbedtls_ecp_group_id *gid;
Manuel Pégourié-Gonnardab240102014-02-04 16:18:07 +01007365
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007366 if (ssl->conf->curve_list == NULL) {
7367 return -1;
7368 }
Manuel Pégourié-Gonnard9d412d82015-06-17 12:10:46 +02007369
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007370 for (gid = ssl->conf->curve_list; *gid != MBEDTLS_ECP_DP_NONE; gid++) {
7371 if (*gid == grp_id) {
7372 return 0;
7373 }
7374 }
Manuel Pégourié-Gonnardab240102014-02-04 16:18:07 +01007375
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007376 return -1;
Manuel Pégourié-Gonnardab240102014-02-04 16:18:07 +01007377}
Manuel Pégourié-Gonnard298d6cc2022-02-14 11:34:47 +01007378
7379/*
7380 * Same as mbedtls_ssl_check_curve() but takes a TLS ID for the curve.
7381 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007382int mbedtls_ssl_check_curve_tls_id(const mbedtls_ssl_context *ssl, uint16_t tls_id)
Manuel Pégourié-Gonnard298d6cc2022-02-14 11:34:47 +01007383{
7384 const mbedtls_ecp_curve_info *curve_info =
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007385 mbedtls_ecp_curve_info_from_tls_id(tls_id);
7386 if (curve_info == NULL) {
7387 return -1;
7388 }
7389 return mbedtls_ssl_check_curve(ssl, curve_info->grp_id);
Manuel Pégourié-Gonnard298d6cc2022-02-14 11:34:47 +01007390}
Manuel Pégourié-Gonnardb541da62015-06-17 11:43:30 +02007391#endif /* MBEDTLS_ECP_C */
Manuel Pégourié-Gonnard7f2a07d2014-04-09 09:50:57 +02007392
Gilles Peskineeccd8882020-03-10 12:19:08 +01007393#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
Manuel Pégourié-Gonnard7bfc1222015-06-17 14:34:48 +02007394/*
7395 * Check if a hash proposed by the peer is in our list.
7396 * Return 0 if we're willing to use it, -1 otherwise.
7397 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007398int mbedtls_ssl_check_sig_hash(const mbedtls_ssl_context *ssl,
7399 mbedtls_md_type_t md)
Manuel Pégourié-Gonnard7bfc1222015-06-17 14:34:48 +02007400{
7401 const int *cur;
7402
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007403 if (ssl->conf->sig_hashes == NULL) {
7404 return -1;
7405 }
Manuel Pégourié-Gonnard7bfc1222015-06-17 14:34:48 +02007406
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007407 for (cur = ssl->conf->sig_hashes; *cur != MBEDTLS_MD_NONE; cur++) {
7408 if (*cur == (int) md) {
7409 return 0;
7410 }
7411 }
Manuel Pégourié-Gonnard7bfc1222015-06-17 14:34:48 +02007412
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007413 return -1;
Manuel Pégourié-Gonnard7bfc1222015-06-17 14:34:48 +02007414}
Gilles Peskineeccd8882020-03-10 12:19:08 +01007415#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
Manuel Pégourié-Gonnard7bfc1222015-06-17 14:34:48 +02007416
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02007417#if defined(MBEDTLS_X509_CRT_PARSE_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007418int mbedtls_ssl_check_cert_usage(const mbedtls_x509_crt *cert,
7419 const mbedtls_ssl_ciphersuite_t *ciphersuite,
7420 int cert_endpoint,
7421 uint32_t *flags)
Manuel Pégourié-Gonnard7f2a07d2014-04-09 09:50:57 +02007422{
Manuel Pégourié-Gonnarde6efa6f2015-04-20 11:01:48 +01007423 int ret = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02007424#if defined(MBEDTLS_X509_CHECK_KEY_USAGE)
Manuel Pégourié-Gonnard7f2a07d2014-04-09 09:50:57 +02007425 int usage = 0;
7426#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02007427#if defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE)
Manuel Pégourié-Gonnard0408fd12014-04-11 11:06:22 +02007428 const char *ext_oid;
7429 size_t ext_len;
7430#endif
7431
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02007432#if !defined(MBEDTLS_X509_CHECK_KEY_USAGE) && \
7433 !defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE)
Manuel Pégourié-Gonnard0408fd12014-04-11 11:06:22 +02007434 ((void) cert);
7435 ((void) cert_endpoint);
Manuel Pégourié-Gonnarde6efa6f2015-04-20 11:01:48 +01007436 ((void) flags);
Manuel Pégourié-Gonnard0408fd12014-04-11 11:06:22 +02007437#endif
Manuel Pégourié-Gonnard7f2a07d2014-04-09 09:50:57 +02007438
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02007439#if defined(MBEDTLS_X509_CHECK_KEY_USAGE)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007440 if (cert_endpoint == MBEDTLS_SSL_IS_SERVER) {
Manuel Pégourié-Gonnard7f2a07d2014-04-09 09:50:57 +02007441 /* Server part of the key exchange */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007442 switch (ciphersuite->key_exchange) {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02007443 case MBEDTLS_KEY_EXCHANGE_RSA:
7444 case MBEDTLS_KEY_EXCHANGE_RSA_PSK:
Manuel Pégourié-Gonnarde6028c92015-04-20 12:19:02 +01007445 usage = MBEDTLS_X509_KU_KEY_ENCIPHERMENT;
Manuel Pégourié-Gonnard7f2a07d2014-04-09 09:50:57 +02007446 break;
7447
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02007448 case MBEDTLS_KEY_EXCHANGE_DHE_RSA:
7449 case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA:
7450 case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA:
7451 usage = MBEDTLS_X509_KU_DIGITAL_SIGNATURE;
Manuel Pégourié-Gonnard7f2a07d2014-04-09 09:50:57 +02007452 break;
7453
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02007454 case MBEDTLS_KEY_EXCHANGE_ECDH_RSA:
7455 case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA:
Manuel Pégourié-Gonnarde6028c92015-04-20 12:19:02 +01007456 usage = MBEDTLS_X509_KU_KEY_AGREEMENT;
Manuel Pégourié-Gonnard7f2a07d2014-04-09 09:50:57 +02007457 break;
7458
7459 /* Don't use default: we want warnings when adding new values */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02007460 case MBEDTLS_KEY_EXCHANGE_NONE:
7461 case MBEDTLS_KEY_EXCHANGE_PSK:
7462 case MBEDTLS_KEY_EXCHANGE_DHE_PSK:
7463 case MBEDTLS_KEY_EXCHANGE_ECDHE_PSK:
Manuel Pégourié-Gonnard557535d2015-09-15 17:53:32 +02007464 case MBEDTLS_KEY_EXCHANGE_ECJPAKE:
Manuel Pégourié-Gonnard7f2a07d2014-04-09 09:50:57 +02007465 usage = 0;
7466 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007467 } else {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02007468 /* Client auth: we only implement rsa_sign and mbedtls_ecdsa_sign for now */
7469 usage = MBEDTLS_X509_KU_DIGITAL_SIGNATURE;
Manuel Pégourié-Gonnard7f2a07d2014-04-09 09:50:57 +02007470 }
7471
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007472 if (mbedtls_x509_crt_check_key_usage(cert, usage) != 0) {
Manuel Pégourié-Gonnarde6028c92015-04-20 12:19:02 +01007473 *flags |= MBEDTLS_X509_BADCERT_KEY_USAGE;
Manuel Pégourié-Gonnarde6efa6f2015-04-20 11:01:48 +01007474 ret = -1;
7475 }
Manuel Pégourié-Gonnard0408fd12014-04-11 11:06:22 +02007476#else
7477 ((void) ciphersuite);
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02007478#endif /* MBEDTLS_X509_CHECK_KEY_USAGE */
Manuel Pégourié-Gonnard7f2a07d2014-04-09 09:50:57 +02007479
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02007480#if defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007481 if (cert_endpoint == MBEDTLS_SSL_IS_SERVER) {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02007482 ext_oid = MBEDTLS_OID_SERVER_AUTH;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007483 ext_len = MBEDTLS_OID_SIZE(MBEDTLS_OID_SERVER_AUTH);
7484 } else {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02007485 ext_oid = MBEDTLS_OID_CLIENT_AUTH;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007486 ext_len = MBEDTLS_OID_SIZE(MBEDTLS_OID_CLIENT_AUTH);
Manuel Pégourié-Gonnard0408fd12014-04-11 11:06:22 +02007487 }
7488
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007489 if (mbedtls_x509_crt_check_extended_key_usage(cert, ext_oid, ext_len) != 0) {
Manuel Pégourié-Gonnarde6028c92015-04-20 12:19:02 +01007490 *flags |= MBEDTLS_X509_BADCERT_EXT_KEY_USAGE;
Manuel Pégourié-Gonnarde6efa6f2015-04-20 11:01:48 +01007491 ret = -1;
7492 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02007493#endif /* MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE */
Manuel Pégourié-Gonnard0408fd12014-04-11 11:06:22 +02007494
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007495 return ret;
Manuel Pégourié-Gonnard7f2a07d2014-04-09 09:50:57 +02007496}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02007497#endif /* MBEDTLS_X509_CRT_PARSE_C */
Manuel Pégourié-Gonnard3a306b92014-04-29 15:11:17 +02007498
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007499int mbedtls_ssl_set_calc_verify_md(mbedtls_ssl_context *ssl, int md)
Simon Butcher99000142016-10-13 17:21:01 +01007500{
7501#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007502 if (ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_3) {
Simon Butcher99000142016-10-13 17:21:01 +01007503 return MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007504 }
Simon Butcher99000142016-10-13 17:21:01 +01007505
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007506 switch (md) {
Simon Butcher99000142016-10-13 17:21:01 +01007507#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1)
7508#if defined(MBEDTLS_MD5_C)
7509 case MBEDTLS_SSL_HASH_MD5:
Janos Follath182013f2016-10-25 10:50:22 +01007510 return MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH;
Simon Butcher99000142016-10-13 17:21:01 +01007511#endif
7512#if defined(MBEDTLS_SHA1_C)
7513 case MBEDTLS_SSL_HASH_SHA1:
7514 ssl->handshake->calc_verify = ssl_calc_verify_tls;
7515 break;
7516#endif
7517#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 */
Gilles Peskined2d59372021-05-12 22:43:27 +02007518#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384)
Simon Butcher99000142016-10-13 17:21:01 +01007519 case MBEDTLS_SSL_HASH_SHA384:
7520 ssl->handshake->calc_verify = ssl_calc_verify_tls_sha384;
7521 break;
7522#endif
7523#if defined(MBEDTLS_SHA256_C)
7524 case MBEDTLS_SSL_HASH_SHA256:
7525 ssl->handshake->calc_verify = ssl_calc_verify_tls_sha256;
7526 break;
7527#endif
7528 default:
7529 return MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH;
7530 }
7531
7532 return 0;
7533#else /* !MBEDTLS_SSL_PROTO_TLS1_2 */
7534 (void) ssl;
7535 (void) md;
7536
7537 return MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH;
7538#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
7539}
7540
Andres Amaya Garcia46f5a3e2017-07-20 16:17:51 +01007541#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
7542 defined(MBEDTLS_SSL_PROTO_TLS1_1)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007543int mbedtls_ssl_get_key_exchange_md_ssl_tls(mbedtls_ssl_context *ssl,
7544 unsigned char *output,
7545 unsigned char *data, size_t data_len)
Andres Amaya Garcia46f5a3e2017-07-20 16:17:51 +01007546{
7547 int ret = 0;
7548 mbedtls_md5_context mbedtls_md5;
7549 mbedtls_sha1_context mbedtls_sha1;
7550
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007551 mbedtls_md5_init(&mbedtls_md5);
7552 mbedtls_sha1_init(&mbedtls_sha1);
Andres Amaya Garcia46f5a3e2017-07-20 16:17:51 +01007553
7554 /*
7555 * digitally-signed struct {
7556 * opaque md5_hash[16];
7557 * opaque sha_hash[20];
7558 * };
7559 *
7560 * md5_hash
7561 * MD5(ClientHello.random + ServerHello.random
7562 * + ServerParams);
7563 * sha_hash
7564 * SHA(ClientHello.random + ServerHello.random
7565 * + ServerParams);
7566 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007567 if ((ret = mbedtls_md5_starts_ret(&mbedtls_md5)) != 0) {
7568 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_md5_starts_ret", ret);
Andres Amaya Garcia46f5a3e2017-07-20 16:17:51 +01007569 goto exit;
7570 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007571 if ((ret = mbedtls_md5_update_ret(&mbedtls_md5,
7572 ssl->handshake->randbytes, 64)) != 0) {
7573 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_md5_update_ret", ret);
Andres Amaya Garcia46f5a3e2017-07-20 16:17:51 +01007574 goto exit;
7575 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007576 if ((ret = mbedtls_md5_update_ret(&mbedtls_md5, data, data_len)) != 0) {
7577 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_md5_update_ret", ret);
Andres Amaya Garcia46f5a3e2017-07-20 16:17:51 +01007578 goto exit;
7579 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007580 if ((ret = mbedtls_md5_finish_ret(&mbedtls_md5, output)) != 0) {
7581 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_md5_finish_ret", ret);
Andres Amaya Garcia46f5a3e2017-07-20 16:17:51 +01007582 goto exit;
7583 }
7584
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007585 if ((ret = mbedtls_sha1_starts_ret(&mbedtls_sha1)) != 0) {
7586 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_sha1_starts_ret", ret);
Andres Amaya Garcia46f5a3e2017-07-20 16:17:51 +01007587 goto exit;
7588 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007589 if ((ret = mbedtls_sha1_update_ret(&mbedtls_sha1,
7590 ssl->handshake->randbytes, 64)) != 0) {
7591 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_sha1_update_ret", ret);
Andres Amaya Garcia46f5a3e2017-07-20 16:17:51 +01007592 goto exit;
7593 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007594 if ((ret = mbedtls_sha1_update_ret(&mbedtls_sha1, data,
7595 data_len)) != 0) {
7596 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_sha1_update_ret", ret);
Andres Amaya Garcia46f5a3e2017-07-20 16:17:51 +01007597 goto exit;
7598 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007599 if ((ret = mbedtls_sha1_finish_ret(&mbedtls_sha1,
7600 output + 16)) != 0) {
7601 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_sha1_finish_ret", ret);
Andres Amaya Garcia46f5a3e2017-07-20 16:17:51 +01007602 goto exit;
7603 }
7604
7605exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007606 mbedtls_md5_free(&mbedtls_md5);
7607 mbedtls_sha1_free(&mbedtls_sha1);
Andres Amaya Garcia46f5a3e2017-07-20 16:17:51 +01007608
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007609 if (ret != 0) {
7610 mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
7611 MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR);
7612 }
Andres Amaya Garcia46f5a3e2017-07-20 16:17:51 +01007613
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007614 return ret;
Andres Amaya Garcia46f5a3e2017-07-20 16:17:51 +01007615
7616}
7617#endif /* MBEDTLS_SSL_PROTO_SSL3 || MBEDTLS_SSL_PROTO_TLS1 || \
7618 MBEDTLS_SSL_PROTO_TLS1_1 */
7619
7620#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
7621 defined(MBEDTLS_SSL_PROTO_TLS1_2)
Andrzej Kurekd6db9be2019-01-10 05:27:10 -05007622
7623#if defined(MBEDTLS_USE_PSA_CRYPTO)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007624int mbedtls_ssl_get_key_exchange_md_tls1_2(mbedtls_ssl_context *ssl,
7625 unsigned char *hash, size_t *hashlen,
7626 unsigned char *data, size_t data_len,
7627 mbedtls_md_type_t md_alg)
Andrzej Kurekd6db9be2019-01-10 05:27:10 -05007628{
Andrzej Kurek814feff2019-01-14 04:35:19 -05007629 psa_status_t status;
Jaeden Amero34973232019-02-20 10:32:28 +00007630 psa_hash_operation_t hash_operation = PSA_HASH_OPERATION_INIT;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007631 psa_algorithm_t hash_alg = mbedtls_psa_translate_md(md_alg);
Andrzej Kurekd6db9be2019-01-10 05:27:10 -05007632
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007633 MBEDTLS_SSL_DEBUG_MSG(3, ("Perform PSA-based computation of digest of ServerKeyExchange"));
Andrzej Kurek814feff2019-01-14 04:35:19 -05007634
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007635 if ((status = psa_hash_setup(&hash_operation,
7636 hash_alg)) != PSA_SUCCESS) {
7637 MBEDTLS_SSL_DEBUG_RET(1, "psa_hash_setup", status);
Andrzej Kurekd6db9be2019-01-10 05:27:10 -05007638 goto exit;
7639 }
7640
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007641 if ((status = psa_hash_update(&hash_operation, ssl->handshake->randbytes,
7642 64)) != PSA_SUCCESS) {
7643 MBEDTLS_SSL_DEBUG_RET(1, "psa_hash_update", status);
Andrzej Kurekd6db9be2019-01-10 05:27:10 -05007644 goto exit;
7645 }
7646
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007647 if ((status = psa_hash_update(&hash_operation,
7648 data, data_len)) != PSA_SUCCESS) {
7649 MBEDTLS_SSL_DEBUG_RET(1, "psa_hash_update", status);
Andrzej Kurekd6db9be2019-01-10 05:27:10 -05007650 goto exit;
7651 }
7652
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007653 if ((status = psa_hash_finish(&hash_operation, hash, PSA_HASH_MAX_SIZE,
7654 hashlen)) != PSA_SUCCESS) {
7655 MBEDTLS_SSL_DEBUG_RET(1, "psa_hash_finish", status);
7656 goto exit;
Andrzej Kurekd6db9be2019-01-10 05:27:10 -05007657 }
7658
7659exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007660 if (status != PSA_SUCCESS) {
7661 mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
7662 MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR);
David Horstmann09072662025-03-12 12:03:13 +00007663
7664 return mbedtls_ssl_md_error_from_psa(status);
Andrzej Kurekd6db9be2019-01-10 05:27:10 -05007665 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007666 return 0;
Andrzej Kurekd6db9be2019-01-10 05:27:10 -05007667}
7668
7669#else
7670
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007671int mbedtls_ssl_get_key_exchange_md_tls1_2(mbedtls_ssl_context *ssl,
7672 unsigned char *hash, size_t *hashlen,
7673 unsigned char *data, size_t data_len,
7674 mbedtls_md_type_t md_alg)
Andres Amaya Garcia46f5a3e2017-07-20 16:17:51 +01007675{
7676 int ret = 0;
7677 mbedtls_md_context_t ctx;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007678 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(md_alg);
7679 *hashlen = mbedtls_md_get_size(md_info);
Andres Amaya Garcia46f5a3e2017-07-20 16:17:51 +01007680
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007681 MBEDTLS_SSL_DEBUG_MSG(3, ("Perform mbedtls-based computation of digest of ServerKeyExchange"));
Andrzej Kurek814feff2019-01-14 04:35:19 -05007682
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007683 mbedtls_md_init(&ctx);
Andres Amaya Garcia46f5a3e2017-07-20 16:17:51 +01007684
7685 /*
7686 * digitally-signed struct {
7687 * opaque client_random[32];
7688 * opaque server_random[32];
7689 * ServerDHParams params;
7690 * };
7691 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007692 if ((ret = mbedtls_md_setup(&ctx, md_info, 0)) != 0) {
7693 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_md_setup", ret);
Andres Amaya Garcia46f5a3e2017-07-20 16:17:51 +01007694 goto exit;
7695 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007696 if ((ret = mbedtls_md_starts(&ctx)) != 0) {
7697 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_md_starts", ret);
Andres Amaya Garcia46f5a3e2017-07-20 16:17:51 +01007698 goto exit;
7699 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007700 if ((ret = mbedtls_md_update(&ctx, ssl->handshake->randbytes, 64)) != 0) {
7701 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_md_update", ret);
Andres Amaya Garcia46f5a3e2017-07-20 16:17:51 +01007702 goto exit;
7703 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007704 if ((ret = mbedtls_md_update(&ctx, data, data_len)) != 0) {
7705 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_md_update", ret);
Andres Amaya Garcia46f5a3e2017-07-20 16:17:51 +01007706 goto exit;
7707 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007708 if ((ret = mbedtls_md_finish(&ctx, hash)) != 0) {
7709 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_md_finish", ret);
Andres Amaya Garcia46f5a3e2017-07-20 16:17:51 +01007710 goto exit;
7711 }
7712
7713exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007714 mbedtls_md_free(&ctx);
Andres Amaya Garcia46f5a3e2017-07-20 16:17:51 +01007715
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007716 if (ret != 0) {
7717 mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
7718 MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR);
7719 }
Andres Amaya Garcia46f5a3e2017-07-20 16:17:51 +01007720
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007721 return ret;
Andres Amaya Garcia46f5a3e2017-07-20 16:17:51 +01007722}
Andrzej Kurekd6db9be2019-01-10 05:27:10 -05007723#endif /* MBEDTLS_USE_PSA_CRYPTO */
7724
Andres Amaya Garcia46f5a3e2017-07-20 16:17:51 +01007725#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \
7726 MBEDTLS_SSL_PROTO_TLS1_2 */
7727
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02007728#endif /* MBEDTLS_SSL_TLS_C */