blob: 1a2bc7bc9ebd1c6c58833a6ce07b7c186c59429d [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
Manuel Pégourié-Gonnard286a1362015-05-13 16:22:05 +020041#if defined(MBEDTLS_SSL_PROTO_DTLS)
Hanno Becker2b1e3542018-08-06 11:19:13 +010042
Hanno Beckera0e20d02019-05-15 14:03:01 +010043#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
Hanno Beckerf8542cf2019-04-09 15:22:03 +010044/* Top-level Connection ID API */
45
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010046int mbedtls_ssl_conf_cid(mbedtls_ssl_config *conf,
47 size_t len,
48 int ignore_other_cid)
Hanno Beckerad4a1372019-05-03 13:06:44 +010049{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010050 if (len > MBEDTLS_SSL_CID_IN_LEN_MAX) {
51 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
52 }
Hanno Beckerad4a1372019-05-03 13:06:44 +010053
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010054 if (ignore_other_cid != MBEDTLS_SSL_UNEXPECTED_CID_FAIL &&
55 ignore_other_cid != MBEDTLS_SSL_UNEXPECTED_CID_IGNORE) {
56 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
Hanno Becker611ac772019-05-14 11:45:26 +010057 }
58
59 conf->ignore_unexpected_cid = ignore_other_cid;
Hanno Beckerad4a1372019-05-03 13:06:44 +010060 conf->cid_len = len;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010061 return 0;
Hanno Beckerad4a1372019-05-03 13:06:44 +010062}
63
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010064int mbedtls_ssl_set_cid(mbedtls_ssl_context *ssl,
65 int enable,
66 unsigned char const *own_cid,
67 size_t own_cid_len)
Hanno Beckerf8542cf2019-04-09 15:22:03 +010068{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010069 if (ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
70 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
71 }
Hanno Becker76a79ab2019-05-03 14:38:32 +010072
Hanno Beckerca092242019-04-25 16:01:49 +010073 ssl->negotiate_cid = enable;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010074 if (enable == MBEDTLS_SSL_CID_DISABLED) {
75 MBEDTLS_SSL_DEBUG_MSG(3, ("Disable use of CID extension."));
76 return 0;
Hanno Beckerca092242019-04-25 16:01:49 +010077 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010078 MBEDTLS_SSL_DEBUG_MSG(3, ("Enable use of CID extension."));
79 MBEDTLS_SSL_DEBUG_BUF(3, "Own CID", own_cid, own_cid_len);
Hanno Beckerca092242019-04-25 16:01:49 +010080
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010081 if (own_cid_len != ssl->conf->cid_len) {
82 MBEDTLS_SSL_DEBUG_MSG(3, ("CID length %u does not match CID length %u in config",
83 (unsigned) own_cid_len,
84 (unsigned) ssl->conf->cid_len));
85 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
Hanno Beckerca092242019-04-25 16:01:49 +010086 }
87
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010088 memcpy(ssl->own_cid, own_cid, own_cid_len);
Hanno Beckerb7ee0cf2019-04-30 14:07:31 +010089 /* Truncation is not an issue here because
90 * MBEDTLS_SSL_CID_IN_LEN_MAX at most 255. */
91 ssl->own_cid_len = (uint8_t) own_cid_len;
Hanno Beckerca092242019-04-25 16:01:49 +010092
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010093 return 0;
Hanno Beckerf8542cf2019-04-09 15:22:03 +010094}
95
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010096int mbedtls_ssl_get_peer_cid(mbedtls_ssl_context *ssl,
97 int *enabled,
98 unsigned char peer_cid[MBEDTLS_SSL_CID_OUT_LEN_MAX],
99 size_t *peer_cid_len)
Hanno Beckerf8542cf2019-04-09 15:22:03 +0100100{
Hanno Beckerf8542cf2019-04-09 15:22:03 +0100101 *enabled = MBEDTLS_SSL_CID_DISABLED;
Hanno Beckerb1f89cd2019-04-26 17:08:02 +0100102
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100103 if (ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM ||
104 ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER) {
105 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
Hanno Becker76a79ab2019-05-03 14:38:32 +0100106 }
Hanno Beckerb1f89cd2019-04-26 17:08:02 +0100107
Hanno Beckerc5f24222019-05-03 12:54:52 +0100108 /* We report MBEDTLS_SSL_CID_DISABLED in case the CID extensions
109 * were used, but client and server requested the empty CID.
110 * This is indistinguishable from not using the CID extension
111 * in the first place. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100112 if (ssl->transform_in->in_cid_len == 0 &&
113 ssl->transform_in->out_cid_len == 0) {
114 return 0;
Hanno Beckerb1f89cd2019-04-26 17:08:02 +0100115 }
116
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100117 if (peer_cid_len != NULL) {
Hanno Becker615ef172019-05-22 16:50:35 +0100118 *peer_cid_len = ssl->transform_in->out_cid_len;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100119 if (peer_cid != NULL) {
120 memcpy(peer_cid, ssl->transform_in->out_cid,
121 ssl->transform_in->out_cid_len);
Hanno Becker615ef172019-05-22 16:50:35 +0100122 }
123 }
Hanno Beckerb1f89cd2019-04-26 17:08:02 +0100124
125 *enabled = MBEDTLS_SSL_CID_ENABLED;
126
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100127 return 0;
Hanno Beckerf8542cf2019-04-09 15:22:03 +0100128}
Hanno Beckera0e20d02019-05-15 14:03:01 +0100129#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
Hanno Beckerf8542cf2019-04-09 15:22:03 +0100130
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200131#endif /* MBEDTLS_SSL_PROTO_DTLS */
Manuel Pégourié-Gonnard0ac247f2014-09-30 22:21:31 +0200132
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200133#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
Manuel Pégourié-Gonnard581e6b62013-07-18 12:32:27 +0200134/*
135 * Convert max_fragment_length codes to length.
136 * RFC 6066 says:
137 * enum{
138 * 2^9(1), 2^10(2), 2^11(3), 2^12(4), (255)
139 * } MaxFragmentLength;
140 * and we add 0 -> extension unused
141 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100142static unsigned int ssl_mfl_code_to_length(int mfl)
Manuel Pégourié-Gonnard581e6b62013-07-18 12:32:27 +0200143{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100144 switch (mfl) {
145 case MBEDTLS_SSL_MAX_FRAG_LEN_NONE:
146 return MBEDTLS_TLS_EXT_ADV_CONTENT_LEN;
147 case MBEDTLS_SSL_MAX_FRAG_LEN_512:
148 return 512;
149 case MBEDTLS_SSL_MAX_FRAG_LEN_1024:
150 return 1024;
151 case MBEDTLS_SSL_MAX_FRAG_LEN_2048:
152 return 2048;
153 case MBEDTLS_SSL_MAX_FRAG_LEN_4096:
154 return 4096;
155 default:
156 return MBEDTLS_TLS_EXT_ADV_CONTENT_LEN;
Angus Grattond8213d02016-05-25 20:56:48 +1000157 }
158}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200159#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
Manuel Pégourié-Gonnard581e6b62013-07-18 12:32:27 +0200160
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100161int mbedtls_ssl_session_copy(mbedtls_ssl_session *dst,
162 const mbedtls_ssl_session *src)
Manuel Pégourié-Gonnard06650f62013-08-02 15:34:52 +0200163{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100164 mbedtls_ssl_session_free(dst);
165 memcpy(dst, src, sizeof(mbedtls_ssl_session));
Manuel Pégourié-Gonnard06650f62013-08-02 15:34:52 +0200166
吴敬辉0f6c6bc2021-11-29 10:46:35 +0800167#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
168 dst->ticket = NULL;
169#endif
170
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200171#if defined(MBEDTLS_X509_CRT_PARSE_C)
Hanno Becker6d1986e2019-02-07 12:27:42 +0000172
173#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100174 if (src->peer_cert != NULL) {
Janos Follath865b3eb2019-12-16 11:46:15 +0000175 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker2292d1f2013-09-15 17:06:49 +0200176
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100177 dst->peer_cert = mbedtls_calloc(1, sizeof(mbedtls_x509_crt));
178 if (dst->peer_cert == NULL) {
179 return MBEDTLS_ERR_SSL_ALLOC_FAILED;
180 }
Manuel Pégourié-Gonnard06650f62013-08-02 15:34:52 +0200181
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100182 mbedtls_x509_crt_init(dst->peer_cert);
Manuel Pégourié-Gonnard06650f62013-08-02 15:34:52 +0200183
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100184 if ((ret = mbedtls_x509_crt_parse_der(dst->peer_cert, src->peer_cert->raw.p,
185 src->peer_cert->raw.len)) != 0) {
186 mbedtls_free(dst->peer_cert);
Manuel Pégourié-Gonnard06650f62013-08-02 15:34:52 +0200187 dst->peer_cert = NULL;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100188 return ret;
Manuel Pégourié-Gonnard06650f62013-08-02 15:34:52 +0200189 }
190 }
Hanno Becker6d1986e2019-02-07 12:27:42 +0000191#else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100192 if (src->peer_cert_digest != NULL) {
Hanno Becker9198ad12019-02-05 17:00:50 +0000193 dst->peer_cert_digest =
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100194 mbedtls_calloc(1, src->peer_cert_digest_len);
195 if (dst->peer_cert_digest == NULL) {
196 return MBEDTLS_ERR_SSL_ALLOC_FAILED;
197 }
Hanno Becker9198ad12019-02-05 17:00:50 +0000198
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100199 memcpy(dst->peer_cert_digest, src->peer_cert_digest,
200 src->peer_cert_digest_len);
Hanno Becker9198ad12019-02-05 17:00:50 +0000201 dst->peer_cert_digest_type = src->peer_cert_digest_type;
Hanno Beckeraccc5992019-02-25 10:06:59 +0000202 dst->peer_cert_digest_len = src->peer_cert_digest_len;
Hanno Becker9198ad12019-02-05 17:00:50 +0000203 }
204#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
205
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200206#endif /* MBEDTLS_X509_CRT_PARSE_C */
Manuel Pégourié-Gonnard06650f62013-08-02 15:34:52 +0200207
Manuel Pégourié-Gonnardb596abf2015-05-20 10:45:29 +0200208#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100209 if (src->ticket != NULL) {
210 dst->ticket = mbedtls_calloc(1, src->ticket_len);
211 if (dst->ticket == NULL) {
212 return MBEDTLS_ERR_SSL_ALLOC_FAILED;
213 }
Manuel Pégourié-Gonnard06650f62013-08-02 15:34:52 +0200214
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100215 memcpy(dst->ticket, src->ticket, src->ticket_len);
Manuel Pégourié-Gonnard06650f62013-08-02 15:34:52 +0200216 }
Manuel Pégourié-Gonnardb596abf2015-05-20 10:45:29 +0200217#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */
Manuel Pégourié-Gonnard06650f62013-08-02 15:34:52 +0200218
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100219 return 0;
Manuel Pégourié-Gonnard06650f62013-08-02 15:34:52 +0200220}
221
Andrzej Kurek0afa2a12020-03-03 10:39:58 -0500222#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +0200223MBEDTLS_CHECK_RETURN_CRITICAL
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100224static int resize_buffer(unsigned char **buffer, size_t len_new, size_t *len_old)
Andrzej Kurek0afa2a12020-03-03 10:39:58 -0500225{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100226 unsigned char *resized_buffer = mbedtls_calloc(1, len_new);
227 if (resized_buffer == NULL) {
Andrzej Kurek0afa2a12020-03-03 10:39:58 -0500228 return -1;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100229 }
Andrzej Kurek0afa2a12020-03-03 10:39:58 -0500230
231 /* We want to copy len_new bytes when downsizing the buffer, and
232 * len_old bytes when upsizing, so we choose the smaller of two sizes,
233 * to fit one buffer into another. Size checks, ensuring that no data is
234 * lost, are done outside of this function. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100235 memcpy(resized_buffer, *buffer,
236 (len_new < *len_old) ? len_new : *len_old);
237 mbedtls_platform_zeroize(*buffer, *len_old);
238 mbedtls_free(*buffer);
Andrzej Kurek0afa2a12020-03-03 10:39:58 -0500239
240 *buffer = resized_buffer;
241 *len_old = len_new;
242
243 return 0;
244}
Andrzej Kurek4a063792020-10-21 15:08:44 +0200245
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100246static void handle_buffer_resizing(mbedtls_ssl_context *ssl, int downsizing,
247 size_t in_buf_new_len,
248 size_t out_buf_new_len)
Andrzej Kurek4a063792020-10-21 15:08:44 +0200249{
250 int modified = 0;
251 size_t written_in = 0, iv_offset_in = 0, len_offset_in = 0;
252 size_t written_out = 0, iv_offset_out = 0, len_offset_out = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100253 if (ssl->in_buf != NULL) {
Andrzej Kurek4a063792020-10-21 15:08:44 +0200254 written_in = ssl->in_msg - ssl->in_buf;
255 iv_offset_in = ssl->in_iv - ssl->in_buf;
256 len_offset_in = ssl->in_len - ssl->in_buf;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100257 if (downsizing ?
Andrzej Kurek4a063792020-10-21 15:08:44 +0200258 ssl->in_buf_len > in_buf_new_len && ssl->in_left < in_buf_new_len :
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100259 ssl->in_buf_len < in_buf_new_len) {
260 if (resize_buffer(&ssl->in_buf, in_buf_new_len, &ssl->in_buf_len) != 0) {
261 MBEDTLS_SSL_DEBUG_MSG(1, ("input buffer resizing failed - out of memory"));
262 } else {
263 MBEDTLS_SSL_DEBUG_MSG(2, ("Reallocating in_buf to %" MBEDTLS_PRINTF_SIZET,
264 in_buf_new_len));
Andrzej Kurek4a063792020-10-21 15:08:44 +0200265 modified = 1;
266 }
267 }
268 }
269
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100270 if (ssl->out_buf != NULL) {
Andrzej Kurek4a063792020-10-21 15:08:44 +0200271 written_out = ssl->out_msg - ssl->out_buf;
272 iv_offset_out = ssl->out_iv - ssl->out_buf;
273 len_offset_out = ssl->out_len - ssl->out_buf;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100274 if (downsizing ?
Andrzej Kurek4a063792020-10-21 15:08:44 +0200275 ssl->out_buf_len > out_buf_new_len && ssl->out_left < out_buf_new_len :
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100276 ssl->out_buf_len < out_buf_new_len) {
277 if (resize_buffer(&ssl->out_buf, out_buf_new_len, &ssl->out_buf_len) != 0) {
278 MBEDTLS_SSL_DEBUG_MSG(1, ("output buffer resizing failed - out of memory"));
279 } else {
280 MBEDTLS_SSL_DEBUG_MSG(2, ("Reallocating out_buf to %" MBEDTLS_PRINTF_SIZET,
281 out_buf_new_len));
Andrzej Kurek4a063792020-10-21 15:08:44 +0200282 modified = 1;
283 }
284 }
285 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100286 if (modified) {
Andrzej Kurek4a063792020-10-21 15:08:44 +0200287 /* Update pointers here to avoid doing it twice. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100288 mbedtls_ssl_reset_in_out_pointers(ssl);
Andrzej Kurek4a063792020-10-21 15:08:44 +0200289 /* Fields below might not be properly updated with record
290 * splitting or with CID, so they are manually updated here. */
291 ssl->out_msg = ssl->out_buf + written_out;
292 ssl->out_len = ssl->out_buf + len_offset_out;
293 ssl->out_iv = ssl->out_buf + iv_offset_out;
294
295 ssl->in_msg = ssl->in_buf + written_in;
296 ssl->in_len = ssl->in_buf + len_offset_in;
297 ssl->in_iv = ssl->in_buf + iv_offset_in;
298 }
299}
Andrzej Kurek0afa2a12020-03-03 10:39:58 -0500300#endif /* MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH */
301
Paul Bakker5121ce52009-01-03 21:22:43 +0000302/*
303 * Key material generation
304 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200305#if defined(MBEDTLS_SSL_PROTO_SSL3)
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +0200306MBEDTLS_CHECK_RETURN_CRITICAL
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100307static int ssl3_prf(const unsigned char *secret, size_t slen,
308 const char *label,
309 const unsigned char *random, size_t rlen,
310 unsigned char *dstbuf, size_t dlen)
Paul Bakker5f70b252012-09-13 14:23:06 +0000311{
Andres Amaya Garcia33952502017-07-20 16:29:16 +0100312 int ret = 0;
Paul Bakker5f70b252012-09-13 14:23:06 +0000313 size_t i;
Manuel Pégourié-Gonnardc0bf01e2015-07-06 16:11:18 +0200314 mbedtls_md5_context md5;
315 mbedtls_sha1_context sha1;
Paul Bakker5f70b252012-09-13 14:23:06 +0000316 unsigned char padding[16];
317 unsigned char sha1sum[20];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100318 ((void) label);
Paul Bakker5f70b252012-09-13 14:23:06 +0000319
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100320 mbedtls_md5_init(&md5);
321 mbedtls_sha1_init(&sha1);
Paul Bakker5b4af392014-06-26 12:09:34 +0200322
Paul Bakker5f70b252012-09-13 14:23:06 +0000323 /*
324 * SSLv3:
325 * block =
326 * MD5( secret + SHA1( 'A' + secret + random ) ) +
327 * MD5( secret + SHA1( 'BB' + secret + random ) ) +
328 * MD5( secret + SHA1( 'CCC' + secret + random ) ) +
329 * ...
330 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100331 for (i = 0; i < dlen / 16; i++) {
332 memset(padding, (unsigned char) ('A' + i), 1 + i);
Paul Bakker5f70b252012-09-13 14:23:06 +0000333
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100334 if ((ret = mbedtls_sha1_starts_ret(&sha1)) != 0) {
Andres Amaya Garcia1a607a12017-06-29 17:09:42 +0100335 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100336 }
337 if ((ret = mbedtls_sha1_update_ret(&sha1, padding, 1 + i)) != 0) {
Andres Amaya Garcia1a607a12017-06-29 17:09:42 +0100338 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100339 }
340 if ((ret = mbedtls_sha1_update_ret(&sha1, secret, slen)) != 0) {
Andres Amaya Garcia1a607a12017-06-29 17:09:42 +0100341 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100342 }
343 if ((ret = mbedtls_sha1_update_ret(&sha1, random, rlen)) != 0) {
Andres Amaya Garcia1a607a12017-06-29 17:09:42 +0100344 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100345 }
346 if ((ret = mbedtls_sha1_finish_ret(&sha1, sha1sum)) != 0) {
Andres Amaya Garcia1a607a12017-06-29 17:09:42 +0100347 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100348 }
Paul Bakker5f70b252012-09-13 14:23:06 +0000349
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100350 if ((ret = mbedtls_md5_starts_ret(&md5)) != 0) {
Andres Amaya Garcia1a607a12017-06-29 17:09:42 +0100351 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100352 }
353 if ((ret = mbedtls_md5_update_ret(&md5, secret, slen)) != 0) {
Andres Amaya Garcia1a607a12017-06-29 17:09:42 +0100354 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100355 }
356 if ((ret = mbedtls_md5_update_ret(&md5, sha1sum, 20)) != 0) {
Andres Amaya Garcia1a607a12017-06-29 17:09:42 +0100357 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100358 }
359 if ((ret = mbedtls_md5_finish_ret(&md5, dstbuf + i * 16)) != 0) {
Andres Amaya Garcia1a607a12017-06-29 17:09:42 +0100360 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100361 }
Paul Bakker5f70b252012-09-13 14:23:06 +0000362 }
363
Andres Amaya Garcia1a607a12017-06-29 17:09:42 +0100364exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100365 mbedtls_md5_free(&md5);
366 mbedtls_sha1_free(&sha1);
Paul Bakker5f70b252012-09-13 14:23:06 +0000367
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100368 mbedtls_platform_zeroize(padding, sizeof(padding));
369 mbedtls_platform_zeroize(sha1sum, sizeof(sha1sum));
Paul Bakker5f70b252012-09-13 14:23:06 +0000370
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100371 return ret;
Paul Bakker5f70b252012-09-13 14:23:06 +0000372}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200373#endif /* MBEDTLS_SSL_PROTO_SSL3 */
Paul Bakker5f70b252012-09-13 14:23:06 +0000374
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200375#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1)
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +0200376MBEDTLS_CHECK_RETURN_CRITICAL
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100377static int tls1_prf(const unsigned char *secret, size_t slen,
378 const char *label,
379 const unsigned char *random, size_t rlen,
380 unsigned char *dstbuf, size_t dlen)
Paul Bakker5121ce52009-01-03 21:22:43 +0000381{
Paul Bakker23986e52011-04-24 08:57:21 +0000382 size_t nb, hs;
383 size_t i, j, k;
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +0200384 const unsigned char *S1, *S2;
Ron Eldor3b350852019-05-07 18:31:49 +0300385 unsigned char *tmp;
386 size_t tmp_len = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000387 unsigned char h_i[20];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200388 const mbedtls_md_info_t *md_info;
389 mbedtls_md_context_t md_ctx;
Janos Follath865b3eb2019-12-16 11:46:15 +0000390 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnardb7fcca32015-03-26 11:41:28 +0100391
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100392 mbedtls_md_init(&md_ctx);
Paul Bakker5121ce52009-01-03 21:22:43 +0000393
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100394 tmp_len = 20 + strlen(label) + rlen;
395 tmp = mbedtls_calloc(1, tmp_len);
396 if (tmp == NULL) {
Ron Eldor3b350852019-05-07 18:31:49 +0300397 ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
398 goto exit;
399 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000400
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100401 hs = (slen + 1) / 2;
Paul Bakker5121ce52009-01-03 21:22:43 +0000402 S1 = secret;
403 S2 = secret + slen - hs;
404
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100405 nb = strlen(label);
406 memcpy(tmp + 20, label, nb);
407 memcpy(tmp + 20 + nb, random, rlen);
Paul Bakker5121ce52009-01-03 21:22:43 +0000408 nb += rlen;
409
410 /*
411 * First compute P_md5(secret,label+random)[0..dlen]
412 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100413 if ((md_info = mbedtls_md_info_from_type(MBEDTLS_MD_MD5)) == NULL) {
Ron Eldor3b350852019-05-07 18:31:49 +0300414 ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR;
415 goto exit;
416 }
Manuel Pégourié-Gonnard7da726b2015-03-24 18:08:19 +0100417
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100418 if ((ret = mbedtls_md_setup(&md_ctx, md_info, 1)) != 0) {
Ron Eldor3b350852019-05-07 18:31:49 +0300419 goto exit;
420 }
Manuel Pégourié-Gonnardb7fcca32015-03-26 11:41:28 +0100421
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100422 ret = mbedtls_md_hmac_starts(&md_ctx, S1, hs);
423 if (ret != 0) {
Gilles Peskine2b3f21d2021-12-10 21:35:10 +0100424 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100425 }
426 ret = mbedtls_md_hmac_update(&md_ctx, tmp + 20, nb);
427 if (ret != 0) {
Gilles Peskine2b3f21d2021-12-10 21:35:10 +0100428 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100429 }
430 ret = mbedtls_md_hmac_finish(&md_ctx, 4 + tmp);
431 if (ret != 0) {
Gilles Peskine2b3f21d2021-12-10 21:35:10 +0100432 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100433 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000434
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100435 for (i = 0; i < dlen; i += 16) {
436 ret = mbedtls_md_hmac_reset(&md_ctx);
437 if (ret != 0) {
Gilles Peskine2b3f21d2021-12-10 21:35:10 +0100438 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100439 }
440 ret = mbedtls_md_hmac_update(&md_ctx, 4 + tmp, 16 + nb);
441 if (ret != 0) {
Gilles Peskine2b3f21d2021-12-10 21:35:10 +0100442 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100443 }
444 ret = mbedtls_md_hmac_finish(&md_ctx, h_i);
445 if (ret != 0) {
Gilles Peskine2b3f21d2021-12-10 21:35:10 +0100446 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100447 }
Manuel Pégourié-Gonnardb7fcca32015-03-26 11:41:28 +0100448
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100449 ret = mbedtls_md_hmac_reset(&md_ctx);
450 if (ret != 0) {
Gilles Peskine2b3f21d2021-12-10 21:35:10 +0100451 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100452 }
453 ret = mbedtls_md_hmac_update(&md_ctx, 4 + tmp, 16);
454 if (ret != 0) {
Gilles Peskine2b3f21d2021-12-10 21:35:10 +0100455 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100456 }
457 ret = mbedtls_md_hmac_finish(&md_ctx, 4 + tmp);
458 if (ret != 0) {
Gilles Peskine2b3f21d2021-12-10 21:35:10 +0100459 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100460 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000461
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100462 k = (i + 16 > dlen) ? dlen % 16 : 16;
Paul Bakker5121ce52009-01-03 21:22:43 +0000463
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100464 for (j = 0; j < k; j++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000465 dstbuf[i + j] = h_i[j];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100466 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000467 }
468
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100469 mbedtls_md_free(&md_ctx);
Manuel Pégourié-Gonnardb7fcca32015-03-26 11:41:28 +0100470
Paul Bakker5121ce52009-01-03 21:22:43 +0000471 /*
472 * XOR out with P_sha1(secret,label+random)[0..dlen]
473 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100474 if ((md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA1)) == NULL) {
Ron Eldor3b350852019-05-07 18:31:49 +0300475 ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR;
476 goto exit;
477 }
Manuel Pégourié-Gonnard7da726b2015-03-24 18:08:19 +0100478
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100479 if ((ret = mbedtls_md_setup(&md_ctx, md_info, 1)) != 0) {
Ron Eldor3b350852019-05-07 18:31:49 +0300480 goto exit;
481 }
Manuel Pégourié-Gonnardb7fcca32015-03-26 11:41:28 +0100482
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100483 ret = mbedtls_md_hmac_starts(&md_ctx, S2, hs);
484 if (ret != 0) {
Gilles Peskine2b3f21d2021-12-10 21:35:10 +0100485 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100486 }
487 ret = mbedtls_md_hmac_update(&md_ctx, tmp + 20, nb);
488 if (ret != 0) {
Gilles Peskine2b3f21d2021-12-10 21:35:10 +0100489 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100490 }
491 ret = mbedtls_md_hmac_finish(&md_ctx, tmp);
492 if (ret != 0) {
Gilles Peskine2b3f21d2021-12-10 21:35:10 +0100493 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100494 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000495
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100496 for (i = 0; i < dlen; i += 20) {
497 ret = mbedtls_md_hmac_reset(&md_ctx);
498 if (ret != 0) {
Gilles Peskine2b3f21d2021-12-10 21:35:10 +0100499 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100500 }
501 ret = mbedtls_md_hmac_update(&md_ctx, tmp, 20 + nb);
502 if (ret != 0) {
Gilles Peskine2b3f21d2021-12-10 21:35:10 +0100503 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100504 }
505 ret = mbedtls_md_hmac_finish(&md_ctx, h_i);
506 if (ret != 0) {
Gilles Peskine2b3f21d2021-12-10 21:35:10 +0100507 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100508 }
Manuel Pégourié-Gonnardb7fcca32015-03-26 11:41:28 +0100509
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100510 ret = mbedtls_md_hmac_reset(&md_ctx);
511 if (ret != 0) {
Gilles Peskine2b3f21d2021-12-10 21:35:10 +0100512 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100513 }
514 ret = mbedtls_md_hmac_update(&md_ctx, tmp, 20);
515 if (ret != 0) {
Gilles Peskine2b3f21d2021-12-10 21:35:10 +0100516 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100517 }
518 ret = mbedtls_md_hmac_finish(&md_ctx, tmp);
519 if (ret != 0) {
Gilles Peskine2b3f21d2021-12-10 21:35:10 +0100520 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100521 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000522
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100523 k = (i + 20 > dlen) ? dlen % 20 : 20;
Paul Bakker5121ce52009-01-03 21:22:43 +0000524
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100525 for (j = 0; j < k; j++) {
526 dstbuf[i + j] = (unsigned char) (dstbuf[i + j] ^ h_i[j]);
527 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000528 }
529
Ron Eldor3b350852019-05-07 18:31:49 +0300530exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100531 mbedtls_md_free(&md_ctx);
Manuel Pégourié-Gonnardb7fcca32015-03-26 11:41:28 +0100532
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100533 mbedtls_platform_zeroize(tmp, tmp_len);
534 mbedtls_platform_zeroize(h_i, sizeof(h_i));
Paul Bakker5121ce52009-01-03 21:22:43 +0000535
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100536 mbedtls_free(tmp);
537 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000538}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200539#endif /* MBEDTLS_SSL_PROTO_TLS1) || MBEDTLS_SSL_PROTO_TLS1_1 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000540
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200541#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
Andrzej Kurekc929a822019-01-14 03:51:11 -0500542#if defined(MBEDTLS_USE_PSA_CRYPTO)
k-stachowiak81053a52019-08-17 10:30:28 +0200543
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100544static psa_status_t setup_psa_key_derivation(psa_key_derivation_operation_t *derivation,
545 psa_key_id_t key,
546 psa_algorithm_t alg,
547 const unsigned char *seed, size_t seed_length,
548 const unsigned char *label, size_t label_length,
549 size_t capacity)
k-stachowiak81053a52019-08-17 10:30:28 +0200550{
551 psa_status_t status;
552
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100553 status = psa_key_derivation_setup(derivation, alg);
554 if (status != PSA_SUCCESS) {
555 return status;
556 }
k-stachowiak81053a52019-08-17 10:30:28 +0200557
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100558 if (PSA_ALG_IS_TLS12_PRF(alg) || PSA_ALG_IS_TLS12_PSK_TO_MS(alg)) {
559 status = psa_key_derivation_input_bytes(derivation,
560 PSA_KEY_DERIVATION_INPUT_SEED,
561 seed, seed_length);
562 if (status != PSA_SUCCESS) {
563 return status;
564 }
k-stachowiak81053a52019-08-17 10:30:28 +0200565
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100566 if (mbedtls_svc_key_id_is_null(key)) {
Gilles Peskine311f54d2019-09-23 18:19:22 +0200567 status = psa_key_derivation_input_bytes(
568 derivation, PSA_KEY_DERIVATION_INPUT_SECRET,
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100569 NULL, 0);
570 } else {
Gilles Peskine311f54d2019-09-23 18:19:22 +0200571 status = psa_key_derivation_input_key(
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100572 derivation, PSA_KEY_DERIVATION_INPUT_SECRET, key);
Gilles Peskine311f54d2019-09-23 18:19:22 +0200573 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100574 if (status != PSA_SUCCESS) {
575 return status;
576 }
k-stachowiak81053a52019-08-17 10:30:28 +0200577
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100578 status = psa_key_derivation_input_bytes(derivation,
579 PSA_KEY_DERIVATION_INPUT_LABEL,
580 label, label_length);
581 if (status != PSA_SUCCESS) {
582 return status;
583 }
584 } else {
585 return PSA_ERROR_NOT_SUPPORTED;
k-stachowiak81053a52019-08-17 10:30:28 +0200586 }
587
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100588 status = psa_key_derivation_set_capacity(derivation, capacity);
589 if (status != PSA_SUCCESS) {
590 return status;
591 }
k-stachowiak81053a52019-08-17 10:30:28 +0200592
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100593 return PSA_SUCCESS;
k-stachowiak81053a52019-08-17 10:30:28 +0200594}
595
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +0200596MBEDTLS_CHECK_RETURN_CRITICAL
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100597static int tls_prf_generic(mbedtls_md_type_t md_type,
598 const unsigned char *secret, size_t slen,
599 const char *label,
600 const unsigned char *random, size_t rlen,
601 unsigned char *dstbuf, size_t dlen)
Andrzej Kurekc929a822019-01-14 03:51:11 -0500602{
603 psa_status_t status;
604 psa_algorithm_t alg;
Ronald Croncf56a0a2020-08-04 09:51:30 +0200605 psa_key_id_t master_key = MBEDTLS_SVC_KEY_ID_INIT;
Janos Follathda6ac012019-08-16 13:47:29 +0100606 psa_key_derivation_operation_t derivation =
Janos Follath8dee8772019-07-30 12:53:32 +0100607 PSA_KEY_DERIVATION_OPERATION_INIT;
Andrzej Kurekc929a822019-01-14 03:51:11 -0500608
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100609 if (md_type == MBEDTLS_MD_SHA384) {
Andrzej Kurekc929a822019-01-14 03:51:11 -0500610 alg = PSA_ALG_TLS12_PRF(PSA_ALG_SHA_384);
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100611 } else {
Andrzej Kurekc929a822019-01-14 03:51:11 -0500612 alg = PSA_ALG_TLS12_PRF(PSA_ALG_SHA_256);
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100613 }
Andrzej Kurekc929a822019-01-14 03:51:11 -0500614
Gilles Peskine311f54d2019-09-23 18:19:22 +0200615 /* Normally a "secret" should be long enough to be impossible to
616 * find by brute force, and in particular should not be empty. But
617 * this PRF is also used to derive an IV, in particular in EAP-TLS,
618 * and for this use case it makes sense to have a 0-length "secret".
619 * Since the key API doesn't allow importing a key of length 0,
Ronald Croncf56a0a2020-08-04 09:51:30 +0200620 * keep master_key=0, which setup_psa_key_derivation() understands
Gilles Peskine311f54d2019-09-23 18:19:22 +0200621 * to mean a 0-length "secret" input. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100622 if (slen != 0) {
Gilles Peskine311f54d2019-09-23 18:19:22 +0200623 psa_key_attributes_t key_attributes = psa_key_attributes_init();
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100624 psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_DERIVE);
625 psa_set_key_algorithm(&key_attributes, alg);
626 psa_set_key_type(&key_attributes, PSA_KEY_TYPE_DERIVE);
Andrzej Kurekc929a822019-01-14 03:51:11 -0500627
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100628 status = psa_import_key(&key_attributes, secret, slen, &master_key);
629 if (status != PSA_SUCCESS) {
630 return MBEDTLS_ERR_SSL_HW_ACCEL_FAILED;
631 }
Gilles Peskine311f54d2019-09-23 18:19:22 +0200632 }
Andrzej Kurekc929a822019-01-14 03:51:11 -0500633
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100634 status = setup_psa_key_derivation(&derivation,
635 master_key, alg,
636 random, rlen,
637 (unsigned char const *) label,
638 (size_t) strlen(label),
639 dlen);
640 if (status != PSA_SUCCESS) {
641 psa_key_derivation_abort(&derivation);
642 psa_destroy_key(master_key);
643 return MBEDTLS_ERR_SSL_HW_ACCEL_FAILED;
Andrzej Kurekc929a822019-01-14 03:51:11 -0500644 }
645
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100646 status = psa_key_derivation_output_bytes(&derivation, dstbuf, dlen);
647 if (status != PSA_SUCCESS) {
648 psa_key_derivation_abort(&derivation);
649 psa_destroy_key(master_key);
650 return MBEDTLS_ERR_SSL_HW_ACCEL_FAILED;
Andrzej Kurekc929a822019-01-14 03:51:11 -0500651 }
652
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100653 status = psa_key_derivation_abort(&derivation);
654 if (status != PSA_SUCCESS) {
655 psa_destroy_key(master_key);
656 return MBEDTLS_ERR_SSL_HW_ACCEL_FAILED;
Andrzej Kurek70737ca2019-01-14 05:37:13 -0500657 }
Andrzej Kurekc929a822019-01-14 03:51:11 -0500658
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100659 if (!mbedtls_svc_key_id_is_null(master_key)) {
660 status = psa_destroy_key(master_key);
661 }
662 if (status != PSA_SUCCESS) {
663 return MBEDTLS_ERR_SSL_HW_ACCEL_FAILED;
664 }
Andrzej Kurekc929a822019-01-14 03:51:11 -0500665
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100666 return 0;
Andrzej Kurekc929a822019-01-14 03:51:11 -0500667}
668
669#else /* MBEDTLS_USE_PSA_CRYPTO */
670
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +0200671MBEDTLS_CHECK_RETURN_CRITICAL
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100672static int tls_prf_generic(mbedtls_md_type_t md_type,
673 const unsigned char *secret, size_t slen,
674 const char *label,
675 const unsigned char *random, size_t rlen,
676 unsigned char *dstbuf, size_t dlen)
Paul Bakker1ef83d62012-04-11 12:09:53 +0000677{
678 size_t nb;
Manuel Pégourié-Gonnard6890c6b2015-03-26 11:11:49 +0100679 size_t i, j, k, md_len;
Ron Eldor3b350852019-05-07 18:31:49 +0300680 unsigned char *tmp;
681 size_t tmp_len = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200682 unsigned char h_i[MBEDTLS_MD_MAX_SIZE];
683 const mbedtls_md_info_t *md_info;
684 mbedtls_md_context_t md_ctx;
Janos Follath865b3eb2019-12-16 11:46:15 +0000685 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnardb7fcca32015-03-26 11:41:28 +0100686
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100687 mbedtls_md_init(&md_ctx);
Paul Bakker1ef83d62012-04-11 12:09:53 +0000688
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100689 if ((md_info = mbedtls_md_info_from_type(md_type)) == NULL) {
690 return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
691 }
Manuel Pégourié-Gonnard6890c6b2015-03-26 11:11:49 +0100692
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100693 md_len = mbedtls_md_get_size(md_info);
Manuel Pégourié-Gonnard6890c6b2015-03-26 11:11:49 +0100694
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100695 tmp_len = md_len + strlen(label) + rlen;
696 tmp = mbedtls_calloc(1, tmp_len);
697 if (tmp == NULL) {
Ron Eldor3b350852019-05-07 18:31:49 +0300698 ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
699 goto exit;
700 }
Paul Bakker1ef83d62012-04-11 12:09:53 +0000701
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100702 nb = strlen(label);
703 memcpy(tmp + md_len, label, nb);
704 memcpy(tmp + md_len + nb, random, rlen);
Paul Bakker1ef83d62012-04-11 12:09:53 +0000705 nb += rlen;
706
707 /*
708 * Compute P_<hash>(secret, label + random)[0..dlen]
709 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100710 if ((ret = mbedtls_md_setup(&md_ctx, md_info, 1)) != 0) {
Ron Eldor3b350852019-05-07 18:31:49 +0300711 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100712 }
Manuel Pégourié-Gonnardb7fcca32015-03-26 11:41:28 +0100713
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100714 ret = mbedtls_md_hmac_starts(&md_ctx, secret, slen);
715 if (ret != 0) {
Gilles Peskine2b3f21d2021-12-10 21:35:10 +0100716 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100717 }
718 ret = mbedtls_md_hmac_update(&md_ctx, tmp + md_len, nb);
719 if (ret != 0) {
Gilles Peskine2b3f21d2021-12-10 21:35:10 +0100720 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100721 }
722 ret = mbedtls_md_hmac_finish(&md_ctx, tmp);
723 if (ret != 0) {
Gilles Peskine2b3f21d2021-12-10 21:35:10 +0100724 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100725 }
Manuel Pégourié-Gonnard7da726b2015-03-24 18:08:19 +0100726
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100727 for (i = 0; i < dlen; i += md_len) {
728 ret = mbedtls_md_hmac_reset(&md_ctx);
729 if (ret != 0) {
Gilles Peskine2b3f21d2021-12-10 21:35:10 +0100730 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100731 }
732 ret = mbedtls_md_hmac_update(&md_ctx, tmp, md_len + nb);
733 if (ret != 0) {
Gilles Peskine2b3f21d2021-12-10 21:35:10 +0100734 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100735 }
736 ret = mbedtls_md_hmac_finish(&md_ctx, h_i);
737 if (ret != 0) {
Gilles Peskine2b3f21d2021-12-10 21:35:10 +0100738 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100739 }
Manuel Pégourié-Gonnardb7fcca32015-03-26 11:41:28 +0100740
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100741 ret = mbedtls_md_hmac_reset(&md_ctx);
742 if (ret != 0) {
Gilles Peskine2b3f21d2021-12-10 21:35:10 +0100743 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100744 }
745 ret = mbedtls_md_hmac_update(&md_ctx, tmp, md_len);
746 if (ret != 0) {
Gilles Peskine2b3f21d2021-12-10 21:35:10 +0100747 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100748 }
749 ret = mbedtls_md_hmac_finish(&md_ctx, tmp);
750 if (ret != 0) {
Gilles Peskine2b3f21d2021-12-10 21:35:10 +0100751 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100752 }
Paul Bakker1ef83d62012-04-11 12:09:53 +0000753
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100754 k = (i + md_len > dlen) ? dlen % md_len : md_len;
Paul Bakker1ef83d62012-04-11 12:09:53 +0000755
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100756 for (j = 0; j < k; j++) {
Paul Bakker1ef83d62012-04-11 12:09:53 +0000757 dstbuf[i + j] = h_i[j];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100758 }
Paul Bakker1ef83d62012-04-11 12:09:53 +0000759 }
760
Ron Eldor3b350852019-05-07 18:31:49 +0300761exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100762 mbedtls_md_free(&md_ctx);
Manuel Pégourié-Gonnardb7fcca32015-03-26 11:41:28 +0100763
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100764 if (tmp != NULL) {
765 mbedtls_platform_zeroize(tmp, tmp_len);
766 }
Dave Rodgman369f4952022-11-01 16:08:14 +0000767
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100768 mbedtls_platform_zeroize(h_i, sizeof(h_i));
Paul Bakker1ef83d62012-04-11 12:09:53 +0000769
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100770 mbedtls_free(tmp);
Ron Eldor3b350852019-05-07 18:31:49 +0300771
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100772 return ret;
Paul Bakker1ef83d62012-04-11 12:09:53 +0000773}
Andrzej Kurekc929a822019-01-14 03:51:11 -0500774#endif /* MBEDTLS_USE_PSA_CRYPTO */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200775#if defined(MBEDTLS_SHA256_C)
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +0200776MBEDTLS_CHECK_RETURN_CRITICAL
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100777static int tls_prf_sha256(const unsigned char *secret, size_t slen,
778 const char *label,
779 const unsigned char *random, size_t rlen,
780 unsigned char *dstbuf, size_t dlen)
Manuel Pégourié-Gonnard6890c6b2015-03-26 11:11:49 +0100781{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100782 return tls_prf_generic(MBEDTLS_MD_SHA256, secret, slen,
783 label, random, rlen, dstbuf, dlen);
Manuel Pégourié-Gonnard6890c6b2015-03-26 11:11:49 +0100784}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200785#endif /* MBEDTLS_SHA256_C */
Paul Bakker1ef83d62012-04-11 12:09:53 +0000786
Gilles Peskined2d59372021-05-12 22:43:27 +0200787#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384)
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +0200788MBEDTLS_CHECK_RETURN_CRITICAL
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100789static int tls_prf_sha384(const unsigned char *secret, size_t slen,
790 const char *label,
791 const unsigned char *random, size_t rlen,
792 unsigned char *dstbuf, size_t dlen)
Paul Bakkerca4ab492012-04-18 14:23:57 +0000793{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100794 return tls_prf_generic(MBEDTLS_MD_SHA384, secret, slen,
795 label, random, rlen, dstbuf, dlen);
Paul Bakkerca4ab492012-04-18 14:23:57 +0000796}
Gilles Peskined2d59372021-05-12 22:43:27 +0200797#endif /* MBEDTLS_SHA512_C && !MBEDTLS_SHA512_NO_SHA384 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200798#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
Paul Bakkerca4ab492012-04-18 14:23:57 +0000799
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100800static void ssl_update_checksum_start(mbedtls_ssl_context *, const unsigned char *, size_t);
Paul Bakkerd2f068e2013-08-27 21:19:20 +0200801
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200802#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
803 defined(MBEDTLS_SSL_PROTO_TLS1_1)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100804static void ssl_update_checksum_md5sha1(mbedtls_ssl_context *, const unsigned char *, size_t);
Paul Bakkerd2f068e2013-08-27 21:19:20 +0200805#endif
Paul Bakker380da532012-04-18 16:10:25 +0000806
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200807#if defined(MBEDTLS_SSL_PROTO_SSL3)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100808static void ssl_calc_verify_ssl(const mbedtls_ssl_context *, unsigned char *, size_t *);
809static void ssl_calc_finished_ssl(mbedtls_ssl_context *, unsigned char *, int);
Paul Bakkerd2f068e2013-08-27 21:19:20 +0200810#endif
811
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200812#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100813static void ssl_calc_verify_tls(const mbedtls_ssl_context *, unsigned char *, size_t *);
814static void ssl_calc_finished_tls(mbedtls_ssl_context *, unsigned char *, int);
Paul Bakkerd2f068e2013-08-27 21:19:20 +0200815#endif
816
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200817#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
818#if defined(MBEDTLS_SHA256_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100819static void ssl_update_checksum_sha256(mbedtls_ssl_context *, const unsigned char *, size_t);
820static void ssl_calc_verify_tls_sha256(const mbedtls_ssl_context *, unsigned char *, size_t *);
821static void ssl_calc_finished_tls_sha256(mbedtls_ssl_context *, unsigned char *, int);
Paul Bakkerd2f068e2013-08-27 21:19:20 +0200822#endif
Paul Bakker769075d2012-11-24 11:26:46 +0100823
Gilles Peskined2d59372021-05-12 22:43:27 +0200824#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100825static void ssl_update_checksum_sha384(mbedtls_ssl_context *, const unsigned char *, size_t);
826static void ssl_calc_verify_tls_sha384(const mbedtls_ssl_context *, unsigned char *, size_t *);
827static void ssl_calc_finished_tls_sha384(mbedtls_ssl_context *, unsigned char *, int);
Paul Bakker769075d2012-11-24 11:26:46 +0100828#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200829#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
Paul Bakker1ef83d62012-04-11 12:09:53 +0000830
Manuel Pégourié-Gonnard45be3d82019-02-18 23:35:14 +0100831#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) && \
Hanno Becker7d0a5692018-10-23 15:26:22 +0100832 defined(MBEDTLS_USE_PSA_CRYPTO)
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +0200833MBEDTLS_CHECK_RETURN_CRITICAL
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100834static int ssl_use_opaque_psk(mbedtls_ssl_context const *ssl)
Hanno Becker7d0a5692018-10-23 15:26:22 +0100835{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100836 if (ssl->conf->f_psk != NULL) {
Hanno Becker7d0a5692018-10-23 15:26:22 +0100837 /* If we've used a callback to select the PSK,
838 * the static configuration is irrelevant. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100839 if (!mbedtls_svc_key_id_is_null(ssl->handshake->psk_opaque)) {
840 return 1;
841 }
Hanno Becker7d0a5692018-10-23 15:26:22 +0100842
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100843 return 0;
Hanno Becker7d0a5692018-10-23 15:26:22 +0100844 }
845
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100846 if (!mbedtls_svc_key_id_is_null(ssl->conf->psk_opaque)) {
847 return 1;
848 }
Hanno Becker7d0a5692018-10-23 15:26:22 +0100849
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100850 return 0;
Hanno Becker7d0a5692018-10-23 15:26:22 +0100851}
852#endif /* MBEDTLS_USE_PSA_CRYPTO &&
Manuel Pégourié-Gonnard45be3d82019-02-18 23:35:14 +0100853 MBEDTLS_KEY_EXCHANGE_PSK_ENABLED */
Hanno Becker7d0a5692018-10-23 15:26:22 +0100854
Ron Eldorcf280092019-05-14 20:19:13 +0300855#if defined(MBEDTLS_SSL_EXPORT_KEYS)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100856static mbedtls_tls_prf_types tls_prf_get_type(mbedtls_ssl_tls_prf_cb *tls_prf)
Ron Eldorcf280092019-05-14 20:19:13 +0300857{
858#if defined(MBEDTLS_SSL_PROTO_SSL3)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100859 if (tls_prf == ssl3_prf) {
860 return MBEDTLS_SSL_TLS_PRF_SSL3;
861 } else
Ron Eldorcf280092019-05-14 20:19:13 +0300862#endif
863#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100864 if (tls_prf == tls1_prf) {
865 return MBEDTLS_SSL_TLS_PRF_TLS1;
866 } else
Ron Eldorcf280092019-05-14 20:19:13 +0300867#endif
868#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
Gilles Peskined2d59372021-05-12 22:43:27 +0200869#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100870 if (tls_prf == tls_prf_sha384) {
871 return MBEDTLS_SSL_TLS_PRF_SHA384;
872 } else
Ron Eldorcf280092019-05-14 20:19:13 +0300873#endif
874#if defined(MBEDTLS_SHA256_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100875 if (tls_prf == tls_prf_sha256) {
876 return MBEDTLS_SSL_TLS_PRF_SHA256;
877 } else
Ron Eldorcf280092019-05-14 20:19:13 +0300878#endif
879#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100880 return MBEDTLS_SSL_TLS_PRF_NONE;
Ron Eldorcf280092019-05-14 20:19:13 +0300881}
882#endif /* MBEDTLS_SSL_EXPORT_KEYS */
883
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100884int mbedtls_ssl_tls_prf(const mbedtls_tls_prf_types prf,
885 const unsigned char *secret, size_t slen,
886 const char *label,
887 const unsigned char *random, size_t rlen,
888 unsigned char *dstbuf, size_t dlen)
Ron Eldor51d3ab52019-05-12 14:54:30 +0300889{
890 mbedtls_ssl_tls_prf_cb *tls_prf = NULL;
891
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100892 switch (prf) {
Ron Eldor51d3ab52019-05-12 14:54:30 +0300893#if defined(MBEDTLS_SSL_PROTO_SSL3)
894 case MBEDTLS_SSL_TLS_PRF_SSL3:
895 tls_prf = ssl3_prf;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100896 break;
Ron Eldord2f25f72019-05-15 14:54:22 +0300897#endif /* MBEDTLS_SSL_PROTO_SSL3 */
Ron Eldor51d3ab52019-05-12 14:54:30 +0300898#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1)
899 case MBEDTLS_SSL_TLS_PRF_TLS1:
900 tls_prf = tls1_prf;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100901 break;
Ron Eldord2f25f72019-05-15 14:54:22 +0300902#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 */
903
904#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
Gilles Peskined2d59372021-05-12 22:43:27 +0200905#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384)
Ron Eldor51d3ab52019-05-12 14:54:30 +0300906 case MBEDTLS_SSL_TLS_PRF_SHA384:
907 tls_prf = tls_prf_sha384;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100908 break;
Gilles Peskined2d59372021-05-12 22:43:27 +0200909#endif /* MBEDTLS_SHA512_C && !MBEDTLS_SHA512_NO_SHA384 */
Ron Eldor51d3ab52019-05-12 14:54:30 +0300910#if defined(MBEDTLS_SHA256_C)
911 case MBEDTLS_SSL_TLS_PRF_SHA256:
912 tls_prf = tls_prf_sha256;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100913 break;
Ron Eldord2f25f72019-05-15 14:54:22 +0300914#endif /* MBEDTLS_SHA256_C */
915#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100916 default:
917 return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
Ron Eldor51d3ab52019-05-12 14:54:30 +0300918 }
919
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100920 return tls_prf(secret, slen, label, random, rlen, dstbuf, dlen);
Ron Eldor51d3ab52019-05-12 14:54:30 +0300921}
922
Manuel Pégourié-Gonnard9b108c22019-05-06 13:32:17 +0200923/* Type for the TLS PRF */
924typedef int ssl_tls_prf_t(const unsigned char *, size_t, const char *,
925 const unsigned char *, size_t,
926 unsigned char *, size_t);
927
Manuel Pégourié-Gonnarde59ae232019-04-30 11:41:40 +0200928/*
Manuel Pégourié-Gonnardcba40d92019-05-06 12:55:40 +0200929 * Populate a transform structure with session keys and all the other
930 * necessary information.
Manuel Pégourié-Gonnarde59ae232019-04-30 11:41:40 +0200931 *
Manuel Pégourié-Gonnardcba40d92019-05-06 12:55:40 +0200932 * Parameters:
933 * - [in/out]: transform: structure to populate
934 * [in] must be just initialised with mbedtls_ssl_transform_init()
Manuel Pégourié-Gonnardc864f6a2019-05-06 13:48:22 +0200935 * [out] fully populated, ready for use by mbedtls_ssl_{en,de}crypt_buf()
Manuel Pégourié-Gonnard6fa57bf2019-05-10 10:50:04 +0200936 * - [in] ciphersuite
937 * - [in] master
938 * - [in] encrypt_then_mac
939 * - [in] trunc_hmac
940 * - [in] compression
Manuel Pégourié-Gonnard9b108c22019-05-06 13:32:17 +0200941 * - [in] tls_prf: pointer to PRF to use for key derivation
942 * - [in] randbytes: buffer holding ServerHello.random + ClientHello.random
Manuel Pégourié-Gonnardc864f6a2019-05-06 13:48:22 +0200943 * - [in] minor_ver: SSL/TLS minor version
944 * - [in] endpoint: client or server
945 * - [in] ssl: optionally used for:
Manuel Pégourié-Gonnarde07bc202020-02-26 09:53:42 +0100946 * - MBEDTLS_SSL_HW_RECORD_ACCEL: whole context (non-const)
Manuel Pégourié-Gonnardc864f6a2019-05-06 13:48:22 +0200947 * - MBEDTLS_SSL_EXPORT_KEYS: ssl->conf->{f,p}_export_keys
948 * - MBEDTLS_DEBUG_C: ssl->conf->{f,p}_dbg
Manuel Pégourié-Gonnarde59ae232019-04-30 11:41:40 +0200949 */
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +0200950MBEDTLS_CHECK_RETURN_CRITICAL
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100951static int ssl_populate_transform(mbedtls_ssl_transform *transform,
952 int ciphersuite,
953 const unsigned char master[48],
Jarno Lamsac84bd242019-08-16 12:06:56 +0300954#if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC)
Manuel Pégourié-Gonnard6fa57bf2019-05-10 10:50:04 +0200955#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100956 int encrypt_then_mac,
Jarno Lamsac84bd242019-08-16 12:06:56 +0300957#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
Manuel Pégourié-Gonnard6fa57bf2019-05-10 10:50:04 +0200958#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100959 int trunc_hmac,
Jarno Lamsac84bd242019-08-16 12:06:56 +0300960#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
961#endif /* MBEDTLS_SSL_SOME_MODES_USE_MAC */
Manuel Pégourié-Gonnard6fa57bf2019-05-10 10:50:04 +0200962#if defined(MBEDTLS_ZLIB_SUPPORT)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100963 int compression,
Manuel Pégourié-Gonnard6fa57bf2019-05-10 10:50:04 +0200964#endif
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100965 ssl_tls_prf_t tls_prf,
966 const unsigned char randbytes[64],
967 int minor_ver,
968 unsigned endpoint,
Manuel Pégourié-Gonnard7ae6ed42020-03-13 11:28:19 +0100969#if !defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100970 const
Manuel Pégourié-Gonnard7ae6ed42020-03-13 11:28:19 +0100971#endif
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100972 mbedtls_ssl_context *ssl)
Paul Bakker5121ce52009-01-03 21:22:43 +0000973{
Paul Bakkerda02a7f2013-08-31 17:25:14 +0200974 int ret = 0;
Hanno Beckercb1cc802018-11-17 22:27:38 +0000975#if defined(MBEDTLS_USE_PSA_CRYPTO)
976 int psa_fallthrough;
977#endif /* MBEDTLS_USE_PSA_CRYPTO */
David Horstmannd4f22082022-10-26 18:25:14 +0100978 int do_mbedtls_cipher_setup;
Paul Bakker5121ce52009-01-03 21:22:43 +0000979 unsigned char keyblk[256];
980 unsigned char *key1;
981 unsigned char *key2;
Paul Bakker68884e32013-01-07 18:20:04 +0100982 unsigned char *mac_enc;
983 unsigned char *mac_dec;
sander-visser3888b032020-05-06 21:49:46 +0200984 size_t mac_key_len = 0;
Paul Bakkerb9cfaa02013-10-11 18:58:55 +0200985 size_t iv_copy_len;
Hanno Becker88aaf652017-12-27 08:17:40 +0000986 unsigned keylen;
Hanno Beckere694c3e2017-12-27 21:34:08 +0000987 const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200988 const mbedtls_cipher_info_t *cipher_info;
989 const mbedtls_md_info_t *md_info;
Paul Bakker68884e32013-01-07 18:20:04 +0100990
Manuel Pégourié-Gonnardc864f6a2019-05-06 13:48:22 +0200991#if !defined(MBEDTLS_SSL_HW_RECORD_ACCEL) && \
992 !defined(MBEDTLS_SSL_EXPORT_KEYS) && \
Gilles Peskinea6f99a12022-04-13 13:24:56 +0200993 !defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) && \
Manuel Pégourié-Gonnardc864f6a2019-05-06 13:48:22 +0200994 !defined(MBEDTLS_DEBUG_C)
Manuel Pégourié-Gonnarda7505d12019-05-07 10:17:56 +0200995 ssl = NULL; /* make sure we don't use it except for those cases */
Manuel Pégourié-Gonnardc864f6a2019-05-06 13:48:22 +0200996 (void) ssl;
997#endif
998
Manuel Pégourié-Gonnard96fb0ee2019-07-09 12:54:17 +0200999 /*
1000 * Some data just needs copying into the structure
1001 */
Jaeden Amero2de07f12019-06-05 13:32:08 +01001002#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) && \
1003 defined(MBEDTLS_SSL_SOME_MODES_USE_MAC)
Manuel Pégourié-Gonnard6fa57bf2019-05-10 10:50:04 +02001004 transform->encrypt_then_mac = encrypt_then_mac;
Hanno Becker9eddaeb2017-12-27 21:37:21 +00001005#endif
Manuel Pégourié-Gonnardc864f6a2019-05-06 13:48:22 +02001006 transform->minor_ver = minor_ver;
Hanno Beckere694c3e2017-12-27 21:34:08 +00001007
Manuel Pégourié-Gonnard96fb0ee2019-07-09 12:54:17 +02001008#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001009 memcpy(transform->randbytes, randbytes, sizeof(transform->randbytes));
Manuel Pégourié-Gonnard96fb0ee2019-07-09 12:54:17 +02001010#endif
1011
Manuel Pégourié-Gonnard9b108c22019-05-06 13:32:17 +02001012 /*
1013 * Get various info structures
1014 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001015 ciphersuite_info = mbedtls_ssl_ciphersuite_from_id(ciphersuite);
1016 if (ciphersuite_info == NULL) {
1017 MBEDTLS_SSL_DEBUG_MSG(1, ("ciphersuite info for %d not found",
1018 ciphersuite));
1019 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
Manuel Pégourié-Gonnard9b108c22019-05-06 13:32:17 +02001020 }
1021
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001022 cipher_info = mbedtls_cipher_info_from_type(ciphersuite_info->cipher);
1023 if (cipher_info == NULL) {
1024 MBEDTLS_SSL_DEBUG_MSG(1, ("cipher info for %u not found",
1025 ciphersuite_info->cipher));
1026 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
Paul Bakker68884e32013-01-07 18:20:04 +01001027 }
1028
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001029 md_info = mbedtls_md_info_from_type(ciphersuite_info->mac);
1030 if (md_info == NULL) {
1031 MBEDTLS_SSL_DEBUG_MSG(1, ("mbedtls_md info for %u not found",
1032 (unsigned) ciphersuite_info->mac));
1033 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
Paul Bakker68884e32013-01-07 18:20:04 +01001034 }
1035
Hanno Beckera0e20d02019-05-15 14:03:01 +01001036#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
Hanno Becker4bf74652019-04-26 16:22:27 +01001037 /* Copy own and peer's CID if the use of the CID
1038 * extension has been negotiated. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001039 if (ssl->handshake->cid_in_use == MBEDTLS_SSL_CID_ENABLED) {
1040 MBEDTLS_SSL_DEBUG_MSG(3, ("Copy CIDs into SSL transform"));
Hanno Becker8a7f9722019-04-30 13:52:29 +01001041
Hanno Becker05154c32019-05-03 15:23:51 +01001042 transform->in_cid_len = ssl->own_cid_len;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001043 memcpy(transform->in_cid, ssl->own_cid, ssl->own_cid_len);
1044 MBEDTLS_SSL_DEBUG_BUF(3, "Incoming CID", transform->in_cid,
1045 transform->in_cid_len);
Hanno Beckerd1f20352019-05-15 10:21:55 +01001046
1047 transform->out_cid_len = ssl->handshake->peer_cid_len;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001048 memcpy(transform->out_cid, ssl->handshake->peer_cid,
1049 ssl->handshake->peer_cid_len);
1050 MBEDTLS_SSL_DEBUG_BUF(3, "Outgoing CID", transform->out_cid,
1051 transform->out_cid_len);
Hanno Becker4bf74652019-04-26 16:22:27 +01001052 }
Hanno Beckera0e20d02019-05-15 14:03:01 +01001053#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
Hanno Becker4bf74652019-04-26 16:22:27 +01001054
Paul Bakker5121ce52009-01-03 21:22:43 +00001055 /*
Manuel Pégourié-Gonnard9b108c22019-05-06 13:32:17 +02001056 * Compute key block using the PRF
Paul Bakker5121ce52009-01-03 21:22:43 +00001057 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001058 ret = tls_prf(master, 48, "key expansion", randbytes, 64, keyblk, 256);
1059 if (ret != 0) {
1060 MBEDTLS_SSL_DEBUG_RET(1, "prf", ret);
1061 return ret;
Manuel Pégourié-Gonnarde9608182015-03-26 11:47:47 +01001062 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001063
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001064 MBEDTLS_SSL_DEBUG_MSG(3, ("ciphersuite = %s",
1065 mbedtls_ssl_get_ciphersuite_name(ciphersuite)));
1066 MBEDTLS_SSL_DEBUG_BUF(3, "master secret", master, 48);
1067 MBEDTLS_SSL_DEBUG_BUF(4, "random bytes", randbytes, 64);
1068 MBEDTLS_SSL_DEBUG_BUF(4, "key block", keyblk, 256);
Paul Bakker5121ce52009-01-03 21:22:43 +00001069
Paul Bakker5121ce52009-01-03 21:22:43 +00001070 /*
1071 * Determine the appropriate key, IV and MAC length.
1072 */
Paul Bakker68884e32013-01-07 18:20:04 +01001073
Hanno Becker88aaf652017-12-27 08:17:40 +00001074 keylen = cipher_info->key_bitlen / 8;
Manuel Pégourié-Gonnarde800cd82014-06-18 15:34:40 +02001075
Hanno Becker8031d062018-01-03 15:32:31 +00001076#if defined(MBEDTLS_GCM_C) || \
1077 defined(MBEDTLS_CCM_C) || \
1078 defined(MBEDTLS_CHACHAPOLY_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001079 if (cipher_info->mode == MBEDTLS_MODE_GCM ||
Manuel Pégourié-Gonnard2e58e8e2018-06-18 11:16:43 +02001080 cipher_info->mode == MBEDTLS_MODE_CCM ||
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001081 cipher_info->mode == MBEDTLS_MODE_CHACHAPOLY) {
Hanno Beckerf704bef2018-11-16 15:21:18 +00001082 size_t explicit_ivlen;
Manuel Pégourié-Gonnard2e58e8e2018-06-18 11:16:43 +02001083
Manuel Pégourié-Gonnarde800cd82014-06-18 15:34:40 +02001084 transform->maclen = 0;
Hanno Becker81c7b182017-11-09 18:39:33 +00001085 mac_key_len = 0;
Hanno Beckere694c3e2017-12-27 21:34:08 +00001086 transform->taglen =
1087 ciphersuite_info->flags & MBEDTLS_CIPHERSUITE_SHORT_TAG ? 8 : 16;
Manuel Pégourié-Gonnarde800cd82014-06-18 15:34:40 +02001088
Hanno Becker447558d2020-05-28 07:36:33 +01001089 /* All modes haves 96-bit IVs, but the length of the static parts vary
1090 * with mode and version:
1091 * - For GCM and CCM in TLS 1.2, there's a static IV of 4 Bytes
1092 * (to be concatenated with a dynamically chosen IV of 8 Bytes)
Hanno Beckerf93c2d72020-05-28 07:39:43 +01001093 * - For ChaChaPoly in TLS 1.2, and all modes in TLS 1.3, there's
1094 * a static IV of 12 Bytes (to be XOR'ed with the 8 Byte record
1095 * sequence number).
Manuel Pégourié-Gonnard2e58e8e2018-06-18 11:16:43 +02001096 */
Paul Bakker68884e32013-01-07 18:20:04 +01001097 transform->ivlen = 12;
Hanno Beckerf93c2d72020-05-28 07:39:43 +01001098#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001099 if (minor_ver == MBEDTLS_SSL_MINOR_VERSION_4) {
Manuel Pégourié-Gonnard2e58e8e2018-06-18 11:16:43 +02001100 transform->fixed_ivlen = 12;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001101 } else
Hanno Beckerf93c2d72020-05-28 07:39:43 +01001102#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
1103 {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001104 if (cipher_info->mode == MBEDTLS_MODE_CHACHAPOLY) {
Hanno Beckerf93c2d72020-05-28 07:39:43 +01001105 transform->fixed_ivlen = 12;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001106 } else {
Hanno Beckerf93c2d72020-05-28 07:39:43 +01001107 transform->fixed_ivlen = 4;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001108 }
Hanno Beckerf93c2d72020-05-28 07:39:43 +01001109 }
Manuel Pégourié-Gonnarde800cd82014-06-18 15:34:40 +02001110
Manuel Pégourié-Gonnard2e58e8e2018-06-18 11:16:43 +02001111 /* Minimum length of encrypted record */
1112 explicit_ivlen = transform->ivlen - transform->fixed_ivlen;
Hanno Beckere694c3e2017-12-27 21:34:08 +00001113 transform->minlen = explicit_ivlen + transform->taglen;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001114 } else
Hanno Becker8031d062018-01-03 15:32:31 +00001115#endif /* MBEDTLS_GCM_C || MBEDTLS_CCM_C || MBEDTLS_CHACHAPOLY_C */
1116#if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001117 if (cipher_info->mode == MBEDTLS_MODE_STREAM ||
1118 cipher_info->mode == MBEDTLS_MODE_CBC) {
Manuel Pégourié-Gonnarde800cd82014-06-18 15:34:40 +02001119 /* Initialize HMAC contexts */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001120 if ((ret = mbedtls_md_setup(&transform->md_ctx_enc, md_info, 1)) != 0 ||
1121 (ret = mbedtls_md_setup(&transform->md_ctx_dec, md_info, 1)) != 0) {
1122 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_md_setup", ret);
Ron Eldore6992702019-05-07 18:27:13 +03001123 goto end;
Paul Bakker68884e32013-01-07 18:20:04 +01001124 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001125
Manuel Pégourié-Gonnarde800cd82014-06-18 15:34:40 +02001126 /* Get MAC length */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001127 mac_key_len = mbedtls_md_get_size(md_info);
Hanno Becker81c7b182017-11-09 18:39:33 +00001128 transform->maclen = mac_key_len;
Manuel Pégourié-Gonnarde800cd82014-06-18 15:34:40 +02001129
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001130#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
Manuel Pégourié-Gonnarde800cd82014-06-18 15:34:40 +02001131 /*
1132 * If HMAC is to be truncated, we shall keep the leftmost bytes,
1133 * (rfc 6066 page 13 or rfc 2104 section 4),
1134 * so we only need to adjust the length here.
1135 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001136 if (trunc_hmac == MBEDTLS_SSL_TRUNC_HMAC_ENABLED) {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001137 transform->maclen = MBEDTLS_SSL_TRUNCATED_HMAC_LEN;
Hanno Beckere89353a2017-11-20 16:36:41 +00001138
1139#if defined(MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT)
1140 /* Fall back to old, non-compliant version of the truncated
Hanno Becker563423f2017-11-21 17:20:17 +00001141 * HMAC implementation which also truncates the key
1142 * (Mbed TLS versions from 1.3 to 2.6.0) */
Hanno Beckere89353a2017-11-20 16:36:41 +00001143 mac_key_len = transform->maclen;
1144#endif
1145 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001146#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
Manuel Pégourié-Gonnarde800cd82014-06-18 15:34:40 +02001147
1148 /* IV length */
Paul Bakker68884e32013-01-07 18:20:04 +01001149 transform->ivlen = cipher_info->iv_size;
Paul Bakker5121ce52009-01-03 21:22:43 +00001150
Manuel Pégourié-Gonnardeaa76f72014-06-18 16:06:02 +02001151 /* Minimum length */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001152 if (cipher_info->mode == MBEDTLS_MODE_STREAM) {
Manuel Pégourié-Gonnardeaa76f72014-06-18 16:06:02 +02001153 transform->minlen = transform->maclen;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001154 } else {
Manuel Pégourié-Gonnardeaa76f72014-06-18 16:06:02 +02001155 /*
1156 * GenericBlockCipher:
Manuel Pégourié-Gonnard169dd6a2014-11-04 16:15:39 +01001157 * 1. if EtM is in use: one block plus MAC
1158 * otherwise: * first multiple of blocklen greater than maclen
1159 * 2. IV except for SSL3 and TLS 1.0
Manuel Pégourié-Gonnardeaa76f72014-06-18 16:06:02 +02001160 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001161#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001162 if (encrypt_then_mac == MBEDTLS_SSL_ETM_ENABLED) {
Manuel Pégourié-Gonnard169dd6a2014-11-04 16:15:39 +01001163 transform->minlen = transform->maclen
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001164 + cipher_info->block_size;
1165 } else
Manuel Pégourié-Gonnard169dd6a2014-11-04 16:15:39 +01001166#endif
1167 {
1168 transform->minlen = transform->maclen
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001169 + cipher_info->block_size
1170 - transform->maclen % cipher_info->block_size;
Manuel Pégourié-Gonnard169dd6a2014-11-04 16:15:39 +01001171 }
Manuel Pégourié-Gonnardeaa76f72014-06-18 16:06:02 +02001172
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001173#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001174 if (minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ||
1175 minor_ver == MBEDTLS_SSL_MINOR_VERSION_1) {
Manuel Pégourié-Gonnardeaa76f72014-06-18 16:06:02 +02001176 ; /* No need to adjust minlen */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001177 } else
Manuel Pégourié-Gonnardeaa76f72014-06-18 16:06:02 +02001178#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001179#if defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001180 if (minor_ver == MBEDTLS_SSL_MINOR_VERSION_2 ||
1181 minor_ver == MBEDTLS_SSL_MINOR_VERSION_3) {
Manuel Pégourié-Gonnardeaa76f72014-06-18 16:06:02 +02001182 transform->minlen += transform->ivlen;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001183 } else
Manuel Pégourié-Gonnardeaa76f72014-06-18 16:06:02 +02001184#endif
1185 {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001186 MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
Ron Eldore6992702019-05-07 18:27:13 +03001187 ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR;
1188 goto end;
Manuel Pégourié-Gonnardeaa76f72014-06-18 16:06:02 +02001189 }
Paul Bakker68884e32013-01-07 18:20:04 +01001190 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001191 } else
Hanno Becker8031d062018-01-03 15:32:31 +00001192#endif /* MBEDTLS_SSL_SOME_MODES_USE_MAC */
1193 {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001194 MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
1195 return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
Hanno Becker8031d062018-01-03 15:32:31 +00001196 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001197
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001198 MBEDTLS_SSL_DEBUG_MSG(3, ("keylen: %u, minlen: %u, ivlen: %u, maclen: %u",
1199 (unsigned) keylen,
1200 (unsigned) transform->minlen,
1201 (unsigned) transform->ivlen,
1202 (unsigned) transform->maclen));
Paul Bakker5121ce52009-01-03 21:22:43 +00001203
1204 /*
1205 * Finally setup the cipher contexts, IVs and MAC secrets.
1206 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001207#if defined(MBEDTLS_SSL_CLI_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001208 if (endpoint == MBEDTLS_SSL_IS_CLIENT) {
Hanno Becker81c7b182017-11-09 18:39:33 +00001209 key1 = keyblk + mac_key_len * 2;
Hanno Becker88aaf652017-12-27 08:17:40 +00001210 key2 = keyblk + mac_key_len * 2 + keylen;
Paul Bakker5121ce52009-01-03 21:22:43 +00001211
Paul Bakker68884e32013-01-07 18:20:04 +01001212 mac_enc = keyblk;
Hanno Becker81c7b182017-11-09 18:39:33 +00001213 mac_dec = keyblk + mac_key_len;
Paul Bakker5121ce52009-01-03 21:22:43 +00001214
Paul Bakker2e11f7d2010-07-25 14:24:53 +00001215 /*
1216 * This is not used in TLS v1.1.
1217 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001218 iv_copy_len = (transform->fixed_ivlen) ?
1219 transform->fixed_ivlen : transform->ivlen;
1220 memcpy(transform->iv_enc, key2 + keylen, iv_copy_len);
1221 memcpy(transform->iv_dec, key2 + keylen + iv_copy_len,
1222 iv_copy_len);
1223 } else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001224#endif /* MBEDTLS_SSL_CLI_C */
1225#if defined(MBEDTLS_SSL_SRV_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001226 if (endpoint == MBEDTLS_SSL_IS_SERVER) {
Hanno Becker88aaf652017-12-27 08:17:40 +00001227 key1 = keyblk + mac_key_len * 2 + keylen;
Hanno Becker81c7b182017-11-09 18:39:33 +00001228 key2 = keyblk + mac_key_len * 2;
Paul Bakker5121ce52009-01-03 21:22:43 +00001229
Hanno Becker81c7b182017-11-09 18:39:33 +00001230 mac_enc = keyblk + mac_key_len;
Paul Bakker68884e32013-01-07 18:20:04 +01001231 mac_dec = keyblk;
Paul Bakker5121ce52009-01-03 21:22:43 +00001232
Paul Bakker2e11f7d2010-07-25 14:24:53 +00001233 /*
1234 * This is not used in TLS v1.1.
1235 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001236 iv_copy_len = (transform->fixed_ivlen) ?
1237 transform->fixed_ivlen : transform->ivlen;
1238 memcpy(transform->iv_dec, key1 + keylen, iv_copy_len);
1239 memcpy(transform->iv_enc, key1 + keylen + iv_copy_len,
1240 iv_copy_len);
1241 } else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001242#endif /* MBEDTLS_SSL_SRV_C */
Manuel Pégourié-Gonnardd16d1cb2014-11-20 18:15:05 +01001243 {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001244 MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
Ron Eldore6992702019-05-07 18:27:13 +03001245 ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR;
1246 goto end;
Manuel Pégourié-Gonnardd16d1cb2014-11-20 18:15:05 +01001247 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001248
Hanno Beckerd56ed242018-01-03 15:32:51 +00001249#if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001250#if defined(MBEDTLS_SSL_PROTO_SSL3)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001251 if (minor_ver == MBEDTLS_SSL_MINOR_VERSION_0) {
1252 if (mac_key_len > sizeof(transform->mac_enc)) {
1253 MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
Ron Eldore6992702019-05-07 18:27:13 +03001254 ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR;
1255 goto end;
Manuel Pégourié-Gonnard7cfdcb82014-01-18 18:22:55 +01001256 }
1257
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001258 memcpy(transform->mac_enc, mac_enc, mac_key_len);
1259 memcpy(transform->mac_dec, mac_dec, mac_key_len);
1260 } else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001261#endif /* MBEDTLS_SSL_PROTO_SSL3 */
1262#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
1263 defined(MBEDTLS_SSL_PROTO_TLS1_2)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001264 if (minor_ver >= MBEDTLS_SSL_MINOR_VERSION_1) {
Gilles Peskine039fd122018-03-19 19:06:08 +01001265 /* For HMAC-based ciphersuites, initialize the HMAC transforms.
1266 For AEAD-based ciphersuites, there is nothing to do here. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001267 if (mac_key_len != 0) {
1268 ret = mbedtls_md_hmac_starts(&transform->md_ctx_enc,
1269 mac_enc, mac_key_len);
1270 if (ret != 0) {
Gilles Peskine2b3f21d2021-12-10 21:35:10 +01001271 goto end;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001272 }
1273 ret = mbedtls_md_hmac_starts(&transform->md_ctx_dec,
1274 mac_dec, mac_key_len);
1275 if (ret != 0) {
Gilles Peskine2b3f21d2021-12-10 21:35:10 +01001276 goto end;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001277 }
Gilles Peskine039fd122018-03-19 19:06:08 +01001278 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001279 } else
Paul Bakkerd2f068e2013-08-27 21:19:20 +02001280#endif
Paul Bakker577e0062013-08-28 11:57:20 +02001281 {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001282 MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
Ron Eldore6992702019-05-07 18:27:13 +03001283 ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR;
1284 goto end;
Paul Bakker577e0062013-08-28 11:57:20 +02001285 }
Hanno Beckerd56ed242018-01-03 15:32:51 +00001286#endif /* MBEDTLS_SSL_SOME_MODES_USE_MAC */
Paul Bakker68884e32013-01-07 18:20:04 +01001287
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001288#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001289 if (mbedtls_ssl_hw_record_init != NULL) {
sander-visser1abe8ee2020-05-06 21:27:14 +02001290 ret = 0;
Paul Bakker05ef8352012-05-08 09:17:57 +00001291
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001292 MBEDTLS_SSL_DEBUG_MSG(2, ("going for mbedtls_ssl_hw_record_init()"));
Paul Bakker05ef8352012-05-08 09:17:57 +00001293
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001294 if ((ret = mbedtls_ssl_hw_record_init(ssl, key1, key2, keylen,
1295 transform->iv_enc, transform->iv_dec,
1296 iv_copy_len,
1297 mac_enc, mac_dec,
1298 mac_key_len)) != 0) {
1299 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_hw_record_init", ret);
Ron Eldore6992702019-05-07 18:27:13 +03001300 ret = MBEDTLS_ERR_SSL_HW_ACCEL_FAILED;
1301 goto end;
Paul Bakker05ef8352012-05-08 09:17:57 +00001302 }
1303 }
Hanno Beckerd56ed242018-01-03 15:32:51 +00001304#else
1305 ((void) mac_dec);
1306 ((void) mac_enc);
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001307#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */
Paul Bakker05ef8352012-05-08 09:17:57 +00001308
Manuel Pégourié-Gonnard024b6df2015-10-19 13:52:53 +02001309#if defined(MBEDTLS_SSL_EXPORT_KEYS)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001310 if (ssl->conf->f_export_keys != NULL) {
1311 ssl->conf->f_export_keys(ssl->conf->p_export_keys,
1312 master, keyblk,
1313 mac_key_len, keylen,
1314 iv_copy_len);
Robert Cragie4feb7ae2015-10-02 13:33:37 +01001315 }
Ron Eldorf5cc10d2019-05-07 18:33:40 +03001316
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001317 if (ssl->conf->f_export_keys_ext != NULL) {
1318 ssl->conf->f_export_keys_ext(ssl->conf->p_export_keys,
1319 master, keyblk,
1320 mac_key_len, keylen,
1321 iv_copy_len,
1322 randbytes + 32,
1323 randbytes,
1324 tls_prf_get_type(tls_prf));
Ron Eldorf5cc10d2019-05-07 18:33:40 +03001325 }
Robert Cragie4feb7ae2015-10-02 13:33:37 +01001326#endif
1327
David Horstmannd4f22082022-10-26 18:25:14 +01001328 do_mbedtls_cipher_setup = 1;
Hanno Beckerf704bef2018-11-16 15:21:18 +00001329#if defined(MBEDTLS_USE_PSA_CRYPTO)
Hanno Beckercb1cc802018-11-17 22:27:38 +00001330
1331 /* Only use PSA-based ciphers for TLS-1.2.
1332 * That's relevant at least for TLS-1.0, where
1333 * we assume that mbedtls_cipher_crypt() updates
1334 * the structure field for the IV, which the PSA-based
1335 * implementation currently doesn't. */
1336#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001337 if (minor_ver == MBEDTLS_SSL_MINOR_VERSION_3) {
1338 ret = mbedtls_cipher_setup_psa(&transform->cipher_ctx_enc,
1339 cipher_info, transform->taglen);
1340 if (ret != 0 && ret != MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE) {
1341 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_cipher_setup_psa", ret);
Ron Eldore6992702019-05-07 18:27:13 +03001342 goto end;
Hanno Beckercb1cc802018-11-17 22:27:38 +00001343 }
1344
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001345 if (ret == 0) {
1346 MBEDTLS_SSL_DEBUG_MSG(3, ("Successfully setup PSA-based encryption cipher context"));
Hanno Beckercb1cc802018-11-17 22:27:38 +00001347 psa_fallthrough = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001348 } else {
1349 MBEDTLS_SSL_DEBUG_MSG(1,
1350 (
1351 "Failed to setup PSA-based cipher context for record encryption - fall through to default setup."));
Hanno Beckercb1cc802018-11-17 22:27:38 +00001352 psa_fallthrough = 1;
1353 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001354 } else {
Hanno Beckercb1cc802018-11-17 22:27:38 +00001355 psa_fallthrough = 1;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001356 }
Hanno Beckercb1cc802018-11-17 22:27:38 +00001357#else
1358 psa_fallthrough = 1;
1359#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
Hanno Beckerf704bef2018-11-16 15:21:18 +00001360
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001361 if (psa_fallthrough == 0) {
David Horstmannd4f22082022-10-26 18:25:14 +01001362 do_mbedtls_cipher_setup = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001363 }
Hanno Beckerf704bef2018-11-16 15:21:18 +00001364#endif /* MBEDTLS_USE_PSA_CRYPTO */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001365 if (do_mbedtls_cipher_setup &&
1366 (ret = mbedtls_cipher_setup(&transform->cipher_ctx_enc,
1367 cipher_info)) != 0) {
1368 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_cipher_setup", ret);
Ron Eldore6992702019-05-07 18:27:13 +03001369 goto end;
Manuel Pégourié-Gonnard88665912013-10-25 18:42:44 +02001370 }
Paul Bakkerda02a7f2013-08-31 17:25:14 +02001371
David Horstmannd4f22082022-10-26 18:25:14 +01001372 do_mbedtls_cipher_setup = 1;
Hanno Beckerf704bef2018-11-16 15:21:18 +00001373#if defined(MBEDTLS_USE_PSA_CRYPTO)
Hanno Beckercb1cc802018-11-17 22:27:38 +00001374 /* Only use PSA-based ciphers for TLS-1.2.
1375 * That's relevant at least for TLS-1.0, where
1376 * we assume that mbedtls_cipher_crypt() updates
1377 * the structure field for the IV, which the PSA-based
1378 * implementation currently doesn't. */
1379#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001380 if (minor_ver == MBEDTLS_SSL_MINOR_VERSION_3) {
1381 ret = mbedtls_cipher_setup_psa(&transform->cipher_ctx_dec,
1382 cipher_info, transform->taglen);
1383 if (ret != 0 && ret != MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE) {
1384 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_cipher_setup_psa", ret);
Ron Eldore6992702019-05-07 18:27:13 +03001385 goto end;
Hanno Beckercb1cc802018-11-17 22:27:38 +00001386 }
1387
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001388 if (ret == 0) {
1389 MBEDTLS_SSL_DEBUG_MSG(3, ("Successfully setup PSA-based decryption cipher context"));
Hanno Beckercb1cc802018-11-17 22:27:38 +00001390 psa_fallthrough = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001391 } else {
1392 MBEDTLS_SSL_DEBUG_MSG(1,
1393 (
1394 "Failed to setup PSA-based cipher context for record decryption - fall through to default setup."));
Hanno Beckercb1cc802018-11-17 22:27:38 +00001395 psa_fallthrough = 1;
1396 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001397 } else {
Hanno Beckercb1cc802018-11-17 22:27:38 +00001398 psa_fallthrough = 1;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001399 }
Hanno Beckercb1cc802018-11-17 22:27:38 +00001400#else
1401 psa_fallthrough = 1;
1402#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
Hanno Beckerf704bef2018-11-16 15:21:18 +00001403
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001404 if (psa_fallthrough == 0) {
David Horstmannd4f22082022-10-26 18:25:14 +01001405 do_mbedtls_cipher_setup = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001406 }
Hanno Beckerf704bef2018-11-16 15:21:18 +00001407#endif /* MBEDTLS_USE_PSA_CRYPTO */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001408 if (do_mbedtls_cipher_setup &&
1409 (ret = mbedtls_cipher_setup(&transform->cipher_ctx_dec,
1410 cipher_info)) != 0) {
1411 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_cipher_setup", ret);
Ron Eldore6992702019-05-07 18:27:13 +03001412 goto end;
Manuel Pégourié-Gonnard88665912013-10-25 18:42:44 +02001413 }
Paul Bakkerda02a7f2013-08-31 17:25:14 +02001414
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001415 if ((ret = mbedtls_cipher_setkey(&transform->cipher_ctx_enc, key1,
1416 cipher_info->key_bitlen,
1417 MBEDTLS_ENCRYPT)) != 0) {
1418 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_cipher_setkey", ret);
Ron Eldore6992702019-05-07 18:27:13 +03001419 goto end;
Manuel Pégourié-Gonnard88665912013-10-25 18:42:44 +02001420 }
Paul Bakkerea6ad3f2013-09-02 14:57:01 +02001421
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001422 if ((ret = mbedtls_cipher_setkey(&transform->cipher_ctx_dec, key2,
1423 cipher_info->key_bitlen,
1424 MBEDTLS_DECRYPT)) != 0) {
1425 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_cipher_setkey", ret);
Ron Eldore6992702019-05-07 18:27:13 +03001426 goto end;
Manuel Pégourié-Gonnard88665912013-10-25 18:42:44 +02001427 }
Paul Bakkerda02a7f2013-08-31 17:25:14 +02001428
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001429#if defined(MBEDTLS_CIPHER_MODE_CBC)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001430 if (cipher_info->mode == MBEDTLS_MODE_CBC) {
1431 if ((ret = mbedtls_cipher_set_padding_mode(&transform->cipher_ctx_enc,
1432 MBEDTLS_PADDING_NONE)) != 0) {
1433 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_cipher_set_padding_mode", ret);
Ron Eldore6992702019-05-07 18:27:13 +03001434 goto end;
Manuel Pégourié-Gonnard126a66f2013-10-25 18:33:32 +02001435 }
Manuel Pégourié-Gonnard88665912013-10-25 18:42:44 +02001436
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001437 if ((ret = mbedtls_cipher_set_padding_mode(&transform->cipher_ctx_dec,
1438 MBEDTLS_PADDING_NONE)) != 0) {
1439 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_cipher_set_padding_mode", ret);
Ron Eldore6992702019-05-07 18:27:13 +03001440 goto end;
Manuel Pégourié-Gonnard88665912013-10-25 18:42:44 +02001441 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001442 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001443#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001444
Paul Bakker5121ce52009-01-03 21:22:43 +00001445
Manuel Pégourié-Gonnardd73b47f2019-05-06 12:44:24 +02001446 /* Initialize Zlib contexts */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001447#if defined(MBEDTLS_ZLIB_SUPPORT)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001448 if (compression == MBEDTLS_SSL_COMPRESS_DEFLATE) {
1449 MBEDTLS_SSL_DEBUG_MSG(3, ("Initializing zlib states"));
Paul Bakker2770fbd2012-07-03 13:30:23 +00001450
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001451 memset(&transform->ctx_deflate, 0, sizeof(transform->ctx_deflate));
1452 memset(&transform->ctx_inflate, 0, sizeof(transform->ctx_inflate));
Paul Bakker2770fbd2012-07-03 13:30:23 +00001453
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001454 if (deflateInit(&transform->ctx_deflate,
1455 Z_DEFAULT_COMPRESSION) != Z_OK ||
1456 inflateInit(&transform->ctx_inflate) != Z_OK) {
1457 MBEDTLS_SSL_DEBUG_MSG(1, ("Failed to initialize compression"));
Ron Eldore6992702019-05-07 18:27:13 +03001458 ret = MBEDTLS_ERR_SSL_COMPRESSION_FAILED;
1459 goto end;
Paul Bakker2770fbd2012-07-03 13:30:23 +00001460 }
1461 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001462#endif /* MBEDTLS_ZLIB_SUPPORT */
Paul Bakker2770fbd2012-07-03 13:30:23 +00001463
Ron Eldore6992702019-05-07 18:27:13 +03001464end:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001465 mbedtls_platform_zeroize(keyblk, sizeof(keyblk));
1466 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001467}
1468
Manuel Pégourié-Gonnard8d2805c2019-04-30 12:08:59 +02001469/*
Manuel Pégourié-Gonnard47e33e12019-05-20 10:10:17 +02001470 * Set appropriate PRF function and other SSL / TLS 1.0/1.1 / TLS1.2 functions
Manuel Pégourié-Gonnard8d2805c2019-04-30 12:08:59 +02001471 *
1472 * Inputs:
1473 * - SSL/TLS minor version
1474 * - hash associated with the ciphersuite (only used by TLS 1.2)
1475 *
Manuel Pégourié-Gonnard31d3ef12019-05-10 10:25:00 +02001476 * Outputs:
Manuel Pégourié-Gonnard8d2805c2019-04-30 12:08:59 +02001477 * - the tls_prf, calc_verify and calc_finished members of handshake structure
1478 */
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +02001479MBEDTLS_CHECK_RETURN_CRITICAL
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001480static int ssl_set_handshake_prfs(mbedtls_ssl_handshake_params *handshake,
1481 int minor_ver,
1482 mbedtls_md_type_t hash)
Manuel Pégourié-Gonnard1b00c4f2019-04-30 11:54:22 +02001483{
Gilles Peskinefc9c07f2021-05-12 22:51:53 +02001484#if !defined(MBEDTLS_SSL_PROTO_TLS1_2) || \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001485 !(defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384))
Manuel Pégourié-Gonnard8d2805c2019-04-30 12:08:59 +02001486 (void) hash;
1487#endif
Manuel Pégourié-Gonnard1b00c4f2019-04-30 11:54:22 +02001488
Manuel Pégourié-Gonnard1b00c4f2019-04-30 11:54:22 +02001489#if defined(MBEDTLS_SSL_PROTO_SSL3)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001490 if (minor_ver == MBEDTLS_SSL_MINOR_VERSION_0) {
Manuel Pégourié-Gonnard1b00c4f2019-04-30 11:54:22 +02001491 handshake->tls_prf = ssl3_prf;
1492 handshake->calc_verify = ssl_calc_verify_ssl;
1493 handshake->calc_finished = ssl_calc_finished_ssl;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001494 } else
Manuel Pégourié-Gonnard1b00c4f2019-04-30 11:54:22 +02001495#endif
1496#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001497 if (minor_ver < MBEDTLS_SSL_MINOR_VERSION_3) {
Manuel Pégourié-Gonnard1b00c4f2019-04-30 11:54:22 +02001498 handshake->tls_prf = tls1_prf;
1499 handshake->calc_verify = ssl_calc_verify_tls;
1500 handshake->calc_finished = ssl_calc_finished_tls;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001501 } else
Manuel Pégourié-Gonnard1b00c4f2019-04-30 11:54:22 +02001502#endif
1503#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
Gilles Peskined2d59372021-05-12 22:43:27 +02001504#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001505 if (minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 &&
1506 hash == MBEDTLS_MD_SHA384) {
Manuel Pégourié-Gonnard1b00c4f2019-04-30 11:54:22 +02001507 handshake->tls_prf = tls_prf_sha384;
1508 handshake->calc_verify = ssl_calc_verify_tls_sha384;
1509 handshake->calc_finished = ssl_calc_finished_tls_sha384;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001510 } else
Manuel Pégourié-Gonnard1b00c4f2019-04-30 11:54:22 +02001511#endif
1512#if defined(MBEDTLS_SHA256_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001513 if (minor_ver == MBEDTLS_SSL_MINOR_VERSION_3) {
Manuel Pégourié-Gonnard1b00c4f2019-04-30 11:54:22 +02001514 handshake->tls_prf = tls_prf_sha256;
1515 handshake->calc_verify = ssl_calc_verify_tls_sha256;
1516 handshake->calc_finished = ssl_calc_finished_tls_sha256;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001517 } else
Manuel Pégourié-Gonnard1b00c4f2019-04-30 11:54:22 +02001518#endif
1519#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
1520 {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001521 return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
Manuel Pégourié-Gonnard1b00c4f2019-04-30 11:54:22 +02001522 }
1523
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001524 return 0;
Manuel Pégourié-Gonnard1b00c4f2019-04-30 11:54:22 +02001525}
1526
Manuel Pégourié-Gonnard9951b712019-04-30 12:08:59 +02001527/*
Manuel Pégourié-Gonnard85680c42019-05-03 09:16:16 +02001528 * Compute master secret if needed
Manuel Pégourié-Gonnardde047ad2019-05-03 09:46:14 +02001529 *
1530 * Parameters:
1531 * [in/out] handshake
1532 * [in] resume, premaster, extended_ms, calc_verify, tls_prf
Manuel Pégourié-Gonnardde718b92019-05-03 11:43:28 +02001533 * (PSA-PSK) ciphersuite_info, psk_opaque
Manuel Pégourié-Gonnardde047ad2019-05-03 09:46:14 +02001534 * [out] premaster (cleared)
Manuel Pégourié-Gonnardde047ad2019-05-03 09:46:14 +02001535 * [out] master
1536 * [in] ssl: optionally used for debugging, EMS and PSA-PSK
1537 * debug: conf->f_dbg, conf->p_dbg
1538 * EMS: passed to calc_verify (debug + (SSL3) session_negotiate)
Manuel Pégourié-Gonnardde718b92019-05-03 11:43:28 +02001539 * PSA-PSA: minor_ver, conf
Manuel Pégourié-Gonnard9951b712019-04-30 12:08:59 +02001540 */
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +02001541MBEDTLS_CHECK_RETURN_CRITICAL
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001542static int ssl_compute_master(mbedtls_ssl_handshake_params *handshake,
1543 unsigned char *master,
1544 const mbedtls_ssl_context *ssl)
Manuel Pégourié-Gonnard9951b712019-04-30 12:08:59 +02001545{
Janos Follath865b3eb2019-12-16 11:46:15 +00001546 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard9951b712019-04-30 12:08:59 +02001547
1548 /* cf. RFC 5246, Section 8.1:
1549 * "The master secret is always exactly 48 bytes in length." */
1550 size_t const master_secret_len = 48;
1551
1552#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
1553 unsigned char session_hash[48];
1554#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */
1555
Manuel Pégourié-Gonnard85680c42019-05-03 09:16:16 +02001556 /* The label for the KDF used for key expansion.
1557 * This is either "master secret" or "extended master secret"
1558 * depending on whether the Extended Master Secret extension
1559 * is used. */
1560 char const *lbl = "master secret";
1561
1562 /* The salt for the KDF used for key expansion.
1563 * - If the Extended Master Secret extension is not used,
1564 * this is ClientHello.Random + ServerHello.Random
1565 * (see Sect. 8.1 in RFC 5246).
1566 * - If the Extended Master Secret extension is used,
1567 * this is the transcript of the handshake so far.
1568 * (see Sect. 4 in RFC 7627). */
1569 unsigned char const *salt = handshake->randbytes;
1570 size_t salt_len = 64;
1571
Manuel Pégourié-Gonnardde047ad2019-05-03 09:46:14 +02001572#if !defined(MBEDTLS_DEBUG_C) && \
1573 !defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) && \
1574 !(defined(MBEDTLS_USE_PSA_CRYPTO) && \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001575 defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED))
Manuel Pégourié-Gonnarda7505d12019-05-07 10:17:56 +02001576 ssl = NULL; /* make sure we don't use it except for those cases */
Manuel Pégourié-Gonnardde047ad2019-05-03 09:46:14 +02001577 (void) ssl;
1578#endif
Manuel Pégourié-Gonnardde047ad2019-05-03 09:46:14 +02001579
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001580 if (handshake->resume != 0) {
1581 MBEDTLS_SSL_DEBUG_MSG(3, ("no premaster (session resumed)"));
1582 return 0;
Manuel Pégourié-Gonnard9951b712019-04-30 12:08:59 +02001583 }
Manuel Pégourié-Gonnard9951b712019-04-30 12:08:59 +02001584
1585#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001586 if (handshake->extended_ms == MBEDTLS_SSL_EXTENDED_MS_ENABLED) {
Manuel Pégourié-Gonnard85680c42019-05-03 09:16:16 +02001587 lbl = "extended master secret";
1588 salt = session_hash;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001589 handshake->calc_verify(ssl, session_hash, &salt_len);
Manuel Pégourié-Gonnard85680c42019-05-03 09:16:16 +02001590
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001591 MBEDTLS_SSL_DEBUG_BUF(3, "session hash for extended master secret",
1592 session_hash, salt_len);
Manuel Pégourié-Gonnard85680c42019-05-03 09:16:16 +02001593 }
Manuel Pégourié-Gonnard9951b712019-04-30 12:08:59 +02001594#endif /* MBEDTLS_SSL_EXTENDED_MS_ENABLED */
1595
1596#if defined(MBEDTLS_USE_PSA_CRYPTO) && \
Manuel Pégourié-Gonnardde047ad2019-05-03 09:46:14 +02001597 defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001598 if (handshake->ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK &&
Manuel Pégourié-Gonnardde718b92019-05-03 11:43:28 +02001599 ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 &&
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001600 ssl_use_opaque_psk(ssl) == 1) {
Manuel Pégourié-Gonnard85680c42019-05-03 09:16:16 +02001601 /* Perform PSK-to-MS expansion in a single step. */
1602 psa_status_t status;
1603 psa_algorithm_t alg;
Ronald Croncf56a0a2020-08-04 09:51:30 +02001604 psa_key_id_t psk;
Manuel Pégourié-Gonnard85680c42019-05-03 09:16:16 +02001605 psa_key_derivation_operation_t derivation =
1606 PSA_KEY_DERIVATION_OPERATION_INIT;
Manuel Pégourié-Gonnardde718b92019-05-03 11:43:28 +02001607 mbedtls_md_type_t hash_alg = handshake->ciphersuite_info->mac;
Manuel Pégourié-Gonnard9951b712019-04-30 12:08:59 +02001608
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001609 MBEDTLS_SSL_DEBUG_MSG(2, ("perform PSA-based PSK-to-MS expansion"));
Manuel Pégourié-Gonnard9951b712019-04-30 12:08:59 +02001610
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001611 psk = mbedtls_ssl_get_opaque_psk(ssl);
Manuel Pégourié-Gonnard9951b712019-04-30 12:08:59 +02001612
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001613 if (hash_alg == MBEDTLS_MD_SHA384) {
Manuel Pégourié-Gonnard85680c42019-05-03 09:16:16 +02001614 alg = PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA_384);
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001615 } else {
Manuel Pégourié-Gonnard85680c42019-05-03 09:16:16 +02001616 alg = PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA_256);
Manuel Pégourié-Gonnard9951b712019-04-30 12:08:59 +02001617 }
Manuel Pégourié-Gonnard85680c42019-05-03 09:16:16 +02001618
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001619 status = setup_psa_key_derivation(&derivation, psk, alg,
1620 salt, salt_len,
1621 (unsigned char const *) lbl,
1622 (size_t) strlen(lbl),
1623 master_secret_len);
1624 if (status != PSA_SUCCESS) {
1625 psa_key_derivation_abort(&derivation);
1626 return MBEDTLS_ERR_SSL_HW_ACCEL_FAILED;
Manuel Pégourié-Gonnard85680c42019-05-03 09:16:16 +02001627 }
1628
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001629 status = psa_key_derivation_output_bytes(&derivation,
1630 master,
1631 master_secret_len);
1632 if (status != PSA_SUCCESS) {
1633 psa_key_derivation_abort(&derivation);
1634 return MBEDTLS_ERR_SSL_HW_ACCEL_FAILED;
1635 }
1636
1637 status = psa_key_derivation_abort(&derivation);
1638 if (status != PSA_SUCCESS) {
1639 return MBEDTLS_ERR_SSL_HW_ACCEL_FAILED;
1640 }
1641 } else
Manuel Pégourié-Gonnard85680c42019-05-03 09:16:16 +02001642#endif
1643 {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001644 ret = handshake->tls_prf(handshake->premaster, handshake->pmslen,
1645 lbl, salt, salt_len,
1646 master,
1647 master_secret_len);
1648 if (ret != 0) {
1649 MBEDTLS_SSL_DEBUG_RET(1, "prf", ret);
1650 return ret;
Manuel Pégourié-Gonnard85680c42019-05-03 09:16:16 +02001651 }
1652
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001653 MBEDTLS_SSL_DEBUG_BUF(3, "premaster secret",
1654 handshake->premaster,
1655 handshake->pmslen);
Manuel Pégourié-Gonnard85680c42019-05-03 09:16:16 +02001656
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001657 mbedtls_platform_zeroize(handshake->premaster,
1658 sizeof(handshake->premaster));
Manuel Pégourié-Gonnard9951b712019-04-30 12:08:59 +02001659 }
1660
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001661 return 0;
Manuel Pégourié-Gonnard9951b712019-04-30 12:08:59 +02001662}
Manuel Pégourié-Gonnard1b00c4f2019-04-30 11:54:22 +02001663
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001664int mbedtls_ssl_derive_keys(mbedtls_ssl_context *ssl)
Manuel Pégourié-Gonnarde59ae232019-04-30 11:41:40 +02001665{
Janos Follath865b3eb2019-12-16 11:46:15 +00001666 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard8d2805c2019-04-30 12:08:59 +02001667 const mbedtls_ssl_ciphersuite_t * const ciphersuite_info =
1668 ssl->handshake->ciphersuite_info;
Manuel Pégourié-Gonnard1b00c4f2019-04-30 11:54:22 +02001669
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001670 MBEDTLS_SSL_DEBUG_MSG(2, ("=> derive keys"));
Manuel Pégourié-Gonnard040a9512019-05-06 12:05:58 +02001671
1672 /* Set PRF, calc_verify and calc_finished function pointers */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001673 ret = ssl_set_handshake_prfs(ssl->handshake,
1674 ssl->minor_ver,
1675 ciphersuite_info->mac);
1676 if (ret != 0) {
1677 MBEDTLS_SSL_DEBUG_RET(1, "ssl_set_handshake_prfs", ret);
1678 return ret;
Manuel Pégourié-Gonnard8d2805c2019-04-30 12:08:59 +02001679 }
Manuel Pégourié-Gonnard1b00c4f2019-04-30 11:54:22 +02001680
Manuel Pégourié-Gonnard040a9512019-05-06 12:05:58 +02001681 /* Compute master secret if needed */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001682 ret = ssl_compute_master(ssl->handshake,
1683 ssl->session_negotiate->master,
1684 ssl);
1685 if (ret != 0) {
1686 MBEDTLS_SSL_DEBUG_RET(1, "ssl_compute_master", ret);
1687 return ret;
Manuel Pégourié-Gonnard9951b712019-04-30 12:08:59 +02001688 }
1689
Manuel Pégourié-Gonnard040a9512019-05-06 12:05:58 +02001690 /* Swap the client and server random values:
1691 * - MS derivation wanted client+server (RFC 5246 8.1)
1692 * - key derivation wants server+client (RFC 5246 6.3) */
1693 {
1694 unsigned char tmp[64];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001695 memcpy(tmp, ssl->handshake->randbytes, 64);
1696 memcpy(ssl->handshake->randbytes, tmp + 32, 32);
1697 memcpy(ssl->handshake->randbytes + 32, tmp, 32);
1698 mbedtls_platform_zeroize(tmp, sizeof(tmp));
Manuel Pégourié-Gonnard040a9512019-05-06 12:05:58 +02001699 }
1700
1701 /* Populate transform structure */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001702 ret = ssl_populate_transform(ssl->transform_negotiate,
1703 ssl->session_negotiate->ciphersuite,
1704 ssl->session_negotiate->master,
Jarno Lamsac84bd242019-08-16 12:06:56 +03001705#if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC)
Manuel Pégourié-Gonnard6fa57bf2019-05-10 10:50:04 +02001706#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001707 ssl->session_negotiate->encrypt_then_mac,
Jarno Lamsac84bd242019-08-16 12:06:56 +03001708#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
Manuel Pégourié-Gonnard6fa57bf2019-05-10 10:50:04 +02001709#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001710 ssl->session_negotiate->trunc_hmac,
Jarno Lamsac84bd242019-08-16 12:06:56 +03001711#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
1712#endif /* MBEDTLS_SSL_SOME_MODES_USE_MAC */
Manuel Pégourié-Gonnard6fa57bf2019-05-10 10:50:04 +02001713#if defined(MBEDTLS_ZLIB_SUPPORT)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001714 ssl->session_negotiate->compression,
Manuel Pégourié-Gonnard6fa57bf2019-05-10 10:50:04 +02001715#endif
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001716 ssl->handshake->tls_prf,
1717 ssl->handshake->randbytes,
1718 ssl->minor_ver,
1719 ssl->conf->endpoint,
1720 ssl);
1721 if (ret != 0) {
1722 MBEDTLS_SSL_DEBUG_RET(1, "ssl_populate_transform", ret);
1723 return ret;
Manuel Pégourié-Gonnard040a9512019-05-06 12:05:58 +02001724 }
1725
1726 /* We no longer need Server/ClientHello.random values */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001727 mbedtls_platform_zeroize(ssl->handshake->randbytes,
1728 sizeof(ssl->handshake->randbytes));
Manuel Pégourié-Gonnard040a9512019-05-06 12:05:58 +02001729
Manuel Pégourié-Gonnardd73b47f2019-05-06 12:44:24 +02001730 /* Allocate compression buffer */
1731#if defined(MBEDTLS_ZLIB_SUPPORT)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001732 if (ssl->session_negotiate->compression == MBEDTLS_SSL_COMPRESS_DEFLATE &&
1733 ssl->compress_buf == NULL) {
1734 MBEDTLS_SSL_DEBUG_MSG(3, ("Allocating compression buffer"));
1735 ssl->compress_buf = mbedtls_calloc(1, MBEDTLS_SSL_COMPRESS_BUFFER_LEN);
1736 if (ssl->compress_buf == NULL) {
1737 MBEDTLS_SSL_DEBUG_MSG(1, ("alloc(%d bytes) failed",
1738 MBEDTLS_SSL_COMPRESS_BUFFER_LEN));
1739 return MBEDTLS_ERR_SSL_ALLOC_FAILED;
Manuel Pégourié-Gonnardd73b47f2019-05-06 12:44:24 +02001740 }
1741 }
1742#endif
1743
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001744 MBEDTLS_SSL_DEBUG_MSG(2, ("<= derive keys"));
Manuel Pégourié-Gonnard040a9512019-05-06 12:05:58 +02001745
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001746 return 0;
Manuel Pégourié-Gonnarde59ae232019-04-30 11:41:40 +02001747}
1748
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001749#if defined(MBEDTLS_SSL_PROTO_SSL3)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001750void ssl_calc_verify_ssl(const mbedtls_ssl_context *ssl,
1751 unsigned char *hash,
1752 size_t *hlen)
Paul Bakker5121ce52009-01-03 21:22:43 +00001753{
Manuel Pégourié-Gonnardc0bf01e2015-07-06 16:11:18 +02001754 mbedtls_md5_context md5;
1755 mbedtls_sha1_context sha1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001756 unsigned char pad_1[48];
1757 unsigned char pad_2[48];
1758
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001759 MBEDTLS_SSL_DEBUG_MSG(2, ("=> calc verify ssl"));
Paul Bakker5121ce52009-01-03 21:22:43 +00001760
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001761 mbedtls_md5_init(&md5);
1762 mbedtls_sha1_init(&sha1);
Manuel Pégourié-Gonnard001f2b62015-07-06 16:21:13 +02001763
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001764 mbedtls_md5_clone(&md5, &ssl->handshake->fin_md5);
1765 mbedtls_sha1_clone(&sha1, &ssl->handshake->fin_sha1);
Paul Bakker5121ce52009-01-03 21:22:43 +00001766
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001767 memset(pad_1, 0x36, 48);
1768 memset(pad_2, 0x5C, 48);
Paul Bakker5121ce52009-01-03 21:22:43 +00001769
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001770 mbedtls_md5_update_ret(&md5, ssl->session_negotiate->master, 48);
1771 mbedtls_md5_update_ret(&md5, pad_1, 48);
1772 mbedtls_md5_finish_ret(&md5, hash);
Paul Bakker5121ce52009-01-03 21:22:43 +00001773
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001774 mbedtls_md5_starts_ret(&md5);
1775 mbedtls_md5_update_ret(&md5, ssl->session_negotiate->master, 48);
1776 mbedtls_md5_update_ret(&md5, pad_2, 48);
1777 mbedtls_md5_update_ret(&md5, hash, 16);
1778 mbedtls_md5_finish_ret(&md5, hash);
Paul Bakker5121ce52009-01-03 21:22:43 +00001779
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001780 mbedtls_sha1_update_ret(&sha1, ssl->session_negotiate->master, 48);
1781 mbedtls_sha1_update_ret(&sha1, pad_1, 40);
1782 mbedtls_sha1_finish_ret(&sha1, hash + 16);
Paul Bakker380da532012-04-18 16:10:25 +00001783
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001784 mbedtls_sha1_starts_ret(&sha1);
1785 mbedtls_sha1_update_ret(&sha1, ssl->session_negotiate->master, 48);
1786 mbedtls_sha1_update_ret(&sha1, pad_2, 40);
1787 mbedtls_sha1_update_ret(&sha1, hash + 16, 20);
1788 mbedtls_sha1_finish_ret(&sha1, hash + 16);
Paul Bakker380da532012-04-18 16:10:25 +00001789
Manuel Pégourié-Gonnardde718b92019-05-03 11:43:28 +02001790 *hlen = 36;
1791
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001792 MBEDTLS_SSL_DEBUG_BUF(3, "calculated verify result", hash, *hlen);
1793 MBEDTLS_SSL_DEBUG_MSG(2, ("<= calc verify"));
Paul Bakker380da532012-04-18 16:10:25 +00001794
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001795 mbedtls_md5_free(&md5);
1796 mbedtls_sha1_free(&sha1);
Paul Bakker5b4af392014-06-26 12:09:34 +02001797
Paul Bakker380da532012-04-18 16:10:25 +00001798 return;
1799}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001800#endif /* MBEDTLS_SSL_PROTO_SSL3 */
Paul Bakker380da532012-04-18 16:10:25 +00001801
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001802#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001803void ssl_calc_verify_tls(const mbedtls_ssl_context *ssl,
1804 unsigned char *hash,
1805 size_t *hlen)
Paul Bakker380da532012-04-18 16:10:25 +00001806{
Manuel Pégourié-Gonnardc0bf01e2015-07-06 16:11:18 +02001807 mbedtls_md5_context md5;
1808 mbedtls_sha1_context sha1;
Paul Bakker380da532012-04-18 16:10:25 +00001809
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001810 MBEDTLS_SSL_DEBUG_MSG(2, ("=> calc verify tls"));
Paul Bakker380da532012-04-18 16:10:25 +00001811
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001812 mbedtls_md5_init(&md5);
1813 mbedtls_sha1_init(&sha1);
Manuel Pégourié-Gonnard001f2b62015-07-06 16:21:13 +02001814
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001815 mbedtls_md5_clone(&md5, &ssl->handshake->fin_md5);
1816 mbedtls_sha1_clone(&sha1, &ssl->handshake->fin_sha1);
Paul Bakker380da532012-04-18 16:10:25 +00001817
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001818 mbedtls_md5_finish_ret(&md5, hash);
1819 mbedtls_sha1_finish_ret(&sha1, hash + 16);
Paul Bakker380da532012-04-18 16:10:25 +00001820
Manuel Pégourié-Gonnardde718b92019-05-03 11:43:28 +02001821 *hlen = 36;
1822
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001823 MBEDTLS_SSL_DEBUG_BUF(3, "calculated verify result", hash, *hlen);
1824 MBEDTLS_SSL_DEBUG_MSG(2, ("<= calc verify"));
Paul Bakker380da532012-04-18 16:10:25 +00001825
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001826 mbedtls_md5_free(&md5);
1827 mbedtls_sha1_free(&sha1);
Paul Bakker5b4af392014-06-26 12:09:34 +02001828
Paul Bakker380da532012-04-18 16:10:25 +00001829 return;
1830}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001831#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 */
Paul Bakker380da532012-04-18 16:10:25 +00001832
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001833#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
1834#if defined(MBEDTLS_SHA256_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001835void ssl_calc_verify_tls_sha256(const mbedtls_ssl_context *ssl,
1836 unsigned char *hash,
1837 size_t *hlen)
Paul Bakker380da532012-04-18 16:10:25 +00001838{
Andrzej Kurekeb342242019-01-29 09:14:33 -05001839#if defined(MBEDTLS_USE_PSA_CRYPTO)
1840 size_t hash_size;
1841 psa_status_t status;
1842 psa_hash_operation_t sha256_psa = psa_hash_operation_init();
1843
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001844 MBEDTLS_SSL_DEBUG_MSG(2, ("=> PSA calc verify sha256"));
1845 status = psa_hash_clone(&ssl->handshake->fin_sha256_psa, &sha256_psa);
1846 if (status != PSA_SUCCESS) {
1847 MBEDTLS_SSL_DEBUG_MSG(2, ("PSA hash clone failed"));
Andrzej Kurekeb342242019-01-29 09:14:33 -05001848 return;
1849 }
1850
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001851 status = psa_hash_finish(&sha256_psa, hash, 32, &hash_size);
1852 if (status != PSA_SUCCESS) {
1853 MBEDTLS_SSL_DEBUG_MSG(2, ("PSA hash finish failed"));
Andrzej Kurekeb342242019-01-29 09:14:33 -05001854 return;
1855 }
Manuel Pégourié-Gonnardde718b92019-05-03 11:43:28 +02001856
1857 *hlen = 32;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001858 MBEDTLS_SSL_DEBUG_BUF(3, "PSA calculated verify result", hash, *hlen);
1859 MBEDTLS_SSL_DEBUG_MSG(2, ("<= PSA calc verify"));
Andrzej Kurekeb342242019-01-29 09:14:33 -05001860#else
Manuel Pégourié-Gonnardc0bf01e2015-07-06 16:11:18 +02001861 mbedtls_sha256_context sha256;
Paul Bakker380da532012-04-18 16:10:25 +00001862
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001863 mbedtls_sha256_init(&sha256);
Manuel Pégourié-Gonnard001f2b62015-07-06 16:21:13 +02001864
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001865 MBEDTLS_SSL_DEBUG_MSG(2, ("=> calc verify sha256"));
Paul Bakker380da532012-04-18 16:10:25 +00001866
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001867 mbedtls_sha256_clone(&sha256, &ssl->handshake->fin_sha256);
1868 mbedtls_sha256_finish_ret(&sha256, hash);
Paul Bakker380da532012-04-18 16:10:25 +00001869
Manuel Pégourié-Gonnardde718b92019-05-03 11:43:28 +02001870 *hlen = 32;
1871
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001872 MBEDTLS_SSL_DEBUG_BUF(3, "calculated verify result", hash, *hlen);
1873 MBEDTLS_SSL_DEBUG_MSG(2, ("<= calc verify"));
Paul Bakker380da532012-04-18 16:10:25 +00001874
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001875 mbedtls_sha256_free(&sha256);
Andrzej Kurekeb342242019-01-29 09:14:33 -05001876#endif /* MBEDTLS_USE_PSA_CRYPTO */
Paul Bakker380da532012-04-18 16:10:25 +00001877 return;
1878}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001879#endif /* MBEDTLS_SHA256_C */
Paul Bakker380da532012-04-18 16:10:25 +00001880
Gilles Peskined2d59372021-05-12 22:43:27 +02001881#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001882void ssl_calc_verify_tls_sha384(const mbedtls_ssl_context *ssl,
1883 unsigned char *hash,
1884 size_t *hlen)
Paul Bakker380da532012-04-18 16:10:25 +00001885{
Andrzej Kurekeb342242019-01-29 09:14:33 -05001886#if defined(MBEDTLS_USE_PSA_CRYPTO)
1887 size_t hash_size;
1888 psa_status_t status;
Andrzej Kurek972fba52019-01-30 03:29:12 -05001889 psa_hash_operation_t sha384_psa = psa_hash_operation_init();
Andrzej Kurekeb342242019-01-29 09:14:33 -05001890
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001891 MBEDTLS_SSL_DEBUG_MSG(2, ("=> PSA calc verify sha384"));
1892 status = psa_hash_clone(&ssl->handshake->fin_sha384_psa, &sha384_psa);
1893 if (status != PSA_SUCCESS) {
1894 MBEDTLS_SSL_DEBUG_MSG(2, ("PSA hash clone failed"));
Andrzej Kurekeb342242019-01-29 09:14:33 -05001895 return;
1896 }
1897
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001898 status = psa_hash_finish(&sha384_psa, hash, 48, &hash_size);
1899 if (status != PSA_SUCCESS) {
1900 MBEDTLS_SSL_DEBUG_MSG(2, ("PSA hash finish failed"));
Andrzej Kurekeb342242019-01-29 09:14:33 -05001901 return;
1902 }
Manuel Pégourié-Gonnardde718b92019-05-03 11:43:28 +02001903
1904 *hlen = 48;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001905 MBEDTLS_SSL_DEBUG_BUF(3, "PSA calculated verify result", hash, *hlen);
1906 MBEDTLS_SSL_DEBUG_MSG(2, ("<= PSA calc verify"));
Andrzej Kurekeb342242019-01-29 09:14:33 -05001907#else
Manuel Pégourié-Gonnardc0bf01e2015-07-06 16:11:18 +02001908 mbedtls_sha512_context sha512;
Paul Bakker380da532012-04-18 16:10:25 +00001909
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001910 mbedtls_sha512_init(&sha512);
Manuel Pégourié-Gonnard001f2b62015-07-06 16:21:13 +02001911
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001912 MBEDTLS_SSL_DEBUG_MSG(2, ("=> calc verify sha384"));
Paul Bakker380da532012-04-18 16:10:25 +00001913
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001914 mbedtls_sha512_clone(&sha512, &ssl->handshake->fin_sha512);
1915 mbedtls_sha512_finish_ret(&sha512, hash);
Paul Bakker5121ce52009-01-03 21:22:43 +00001916
Manuel Pégourié-Gonnardde718b92019-05-03 11:43:28 +02001917 *hlen = 48;
1918
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001919 MBEDTLS_SSL_DEBUG_BUF(3, "calculated verify result", hash, *hlen);
1920 MBEDTLS_SSL_DEBUG_MSG(2, ("<= calc verify"));
Paul Bakker5121ce52009-01-03 21:22:43 +00001921
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001922 mbedtls_sha512_free(&sha512);
Andrzej Kurekeb342242019-01-29 09:14:33 -05001923#endif /* MBEDTLS_USE_PSA_CRYPTO */
Paul Bakker5121ce52009-01-03 21:22:43 +00001924 return;
1925}
Gilles Peskined2d59372021-05-12 22:43:27 +02001926#endif /* MBEDTLS_SHA512_C && !MBEDTLS_SHA512_NO_SHA384 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001927#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
Paul Bakker5121ce52009-01-03 21:22:43 +00001928
Gilles Peskineeccd8882020-03-10 12:19:08 +01001929#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001930int 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 +02001931{
Manuel Pégourié-Gonnardbd1ae242013-10-14 13:09:25 +02001932 unsigned char *p = ssl->handshake->premaster;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001933 unsigned char *end = p + sizeof(ssl->handshake->premaster);
Guilhem Bryantb5f04e42020-04-01 11:23:58 +01001934 const unsigned char *psk = NULL;
Guilhem Bryant61b0fe62020-03-27 11:12:12 +00001935 size_t psk_len = 0;
Manuel Pégourié-Gonnard4b682962015-05-07 15:59:54 +01001936
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001937 if (mbedtls_ssl_get_psk(ssl, &psk, &psk_len)
1938 == MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED) {
Guilhem Bryantc5285d82020-03-25 17:08:15 +00001939 /*
1940 * This should never happen because the existence of a PSK is always
1941 * checked before calling this function
1942 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001943 MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
1944 return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
Manuel Pégourié-Gonnard4b682962015-05-07 15:59:54 +01001945 }
Manuel Pégourié-Gonnardbd1ae242013-10-14 13:09:25 +02001946
1947 /*
1948 * PMS = struct {
1949 * opaque other_secret<0..2^16-1>;
1950 * opaque psk<0..2^16-1>;
1951 * };
1952 * with "other_secret" depending on the particular key exchange
1953 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001954#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001955 if (key_ex == MBEDTLS_KEY_EXCHANGE_PSK) {
1956 if (end - p < 2) {
1957 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
1958 }
Manuel Pégourié-Gonnardbd1ae242013-10-14 13:09:25 +02001959
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001960 MBEDTLS_PUT_UINT16_BE(psk_len, p, 0);
Joe Subbiania651e6f2021-08-23 11:35:25 +01001961 p += 2;
Manuel Pégourié-Gonnardbc5e5082015-10-21 12:35:29 +02001962
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001963 if (end < p || (size_t) (end - p) < psk_len) {
1964 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
1965 }
Manuel Pégourié-Gonnardbc5e5082015-10-21 12:35:29 +02001966
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001967 memset(p, 0, psk_len);
Manuel Pégourié-Gonnard4b682962015-05-07 15:59:54 +01001968 p += psk_len;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001969 } else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001970#endif /* MBEDTLS_KEY_EXCHANGE_PSK_ENABLED */
1971#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001972 if (key_ex == MBEDTLS_KEY_EXCHANGE_RSA_PSK) {
Manuel Pégourié-Gonnard0fae60b2013-10-14 17:39:48 +02001973 /*
1974 * other_secret already set by the ClientKeyExchange message,
1975 * and is 48 bytes long
1976 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001977 if (end - p < 2) {
1978 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
1979 }
Philippe Antoine747fd532018-05-30 09:13:21 +02001980
Manuel Pégourié-Gonnard0fae60b2013-10-14 17:39:48 +02001981 *p++ = 0;
1982 *p++ = 48;
1983 p += 48;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001984 } else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001985#endif /* MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */
1986#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001987 if (key_ex == MBEDTLS_KEY_EXCHANGE_DHE_PSK) {
Janos Follath865b3eb2019-12-16 11:46:15 +00001988 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard33352052015-06-02 16:17:08 +01001989 size_t len;
Manuel Pégourié-Gonnardbd1ae242013-10-14 13:09:25 +02001990
Manuel Pégourié-Gonnard8df68632014-06-23 17:56:08 +02001991 /* Write length only when we know the actual value */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001992 if ((ret = mbedtls_dhm_calc_secret(&ssl->handshake->dhm_ctx,
1993 p + 2, end - (p + 2), &len,
1994 ssl->conf->f_rng, ssl->conf->p_rng)) != 0) {
1995 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_dhm_calc_secret", ret);
1996 return ret;
Manuel Pégourié-Gonnardbd1ae242013-10-14 13:09:25 +02001997 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001998 MBEDTLS_PUT_UINT16_BE(len, p, 0);
Joe Subbiania651e6f2021-08-23 11:35:25 +01001999 p += 2 + len;
Manuel Pégourié-Gonnardbd1ae242013-10-14 13:09:25 +02002000
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002001 MBEDTLS_SSL_DEBUG_MPI(3, "DHM: K ", &ssl->handshake->dhm_ctx.K);
2002 } else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002003#endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */
2004#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002005 if (key_ex == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK) {
Janos Follath865b3eb2019-12-16 11:46:15 +00002006 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnardbd1ae242013-10-14 13:09:25 +02002007 size_t zlen;
2008
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002009 if ((ret = mbedtls_ecdh_calc_secret(&ssl->handshake->ecdh_ctx, &zlen,
2010 p + 2, end - (p + 2),
2011 ssl->conf->f_rng, ssl->conf->p_rng)) != 0) {
2012 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecdh_calc_secret", ret);
2013 return ret;
Manuel Pégourié-Gonnardbd1ae242013-10-14 13:09:25 +02002014 }
2015
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002016 MBEDTLS_PUT_UINT16_BE(zlen, p, 0);
Joe Subbiania651e6f2021-08-23 11:35:25 +01002017 p += 2 + zlen;
Manuel Pégourié-Gonnardbd1ae242013-10-14 13:09:25 +02002018
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002019 MBEDTLS_SSL_DEBUG_ECDH(3, &ssl->handshake->ecdh_ctx,
2020 MBEDTLS_DEBUG_ECDH_Z);
2021 } else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002022#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
Manuel Pégourié-Gonnardbd1ae242013-10-14 13:09:25 +02002023 {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002024 MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
2025 return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
Manuel Pégourié-Gonnardbd1ae242013-10-14 13:09:25 +02002026 }
2027
2028 /* opaque psk<0..2^16-1>; */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002029 if (end - p < 2) {
2030 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
2031 }
Manuel Pégourié-Gonnardb2bf5a12014-03-25 16:28:12 +01002032
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002033 MBEDTLS_PUT_UINT16_BE(psk_len, p, 0);
Joe Subbiania651e6f2021-08-23 11:35:25 +01002034 p += 2;
Manuel Pégourié-Gonnardbc5e5082015-10-21 12:35:29 +02002035
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002036 if (end < p || (size_t) (end - p) < psk_len) {
2037 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
2038 }
Manuel Pégourié-Gonnardbc5e5082015-10-21 12:35:29 +02002039
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002040 memcpy(p, psk, psk_len);
Manuel Pégourié-Gonnard4b682962015-05-07 15:59:54 +01002041 p += psk_len;
Manuel Pégourié-Gonnardbd1ae242013-10-14 13:09:25 +02002042
2043 ssl->handshake->pmslen = p - ssl->handshake->premaster;
2044
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002045 return 0;
Manuel Pégourié-Gonnardbd1ae242013-10-14 13:09:25 +02002046}
Gilles Peskineeccd8882020-03-10 12:19:08 +01002047#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
Manuel Pégourié-Gonnardbd1ae242013-10-14 13:09:25 +02002048
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002049#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_RENEGOTIATION)
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +02002050MBEDTLS_CHECK_RETURN_CRITICAL
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002051static int ssl_write_hello_request(mbedtls_ssl_context *ssl);
Manuel Pégourié-Gonnarddf3acd82014-10-15 15:07:45 +02002052
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002053#if defined(MBEDTLS_SSL_PROTO_DTLS)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002054int mbedtls_ssl_resend_hello_request(mbedtls_ssl_context *ssl)
Manuel Pégourié-Gonnarddf3acd82014-10-15 15:07:45 +02002055{
2056 /* If renegotiation is not enforced, retransmit until we would reach max
2057 * timeout if we were using the usual handshake doubling scheme */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002058 if (ssl->conf->renego_max_records < 0) {
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02002059 uint32_t ratio = ssl->conf->hs_timeout_max / ssl->conf->hs_timeout_min + 1;
Manuel Pégourié-Gonnarddf3acd82014-10-15 15:07:45 +02002060 unsigned char doublings = 1;
2061
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002062 while (ratio != 0) {
Manuel Pégourié-Gonnarddf3acd82014-10-15 15:07:45 +02002063 ++doublings;
2064 ratio >>= 1;
2065 }
2066
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002067 if (++ssl->renego_records_seen > doublings) {
2068 MBEDTLS_SSL_DEBUG_MSG(2, ("no longer retransmitting hello request"));
2069 return 0;
Manuel Pégourié-Gonnarddf3acd82014-10-15 15:07:45 +02002070 }
2071 }
2072
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002073 return ssl_write_hello_request(ssl);
Manuel Pégourié-Gonnarddf3acd82014-10-15 15:07:45 +02002074}
2075#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002076#endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_RENEGOTIATION */
Manuel Pégourié-Gonnard26a4cf62014-10-15 13:52:48 +02002077
Hanno Beckerb9d44792019-02-08 07:19:04 +00002078#if defined(MBEDTLS_X509_CRT_PARSE_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002079static void ssl_clear_peer_cert(mbedtls_ssl_session *session)
Hanno Beckerb9d44792019-02-08 07:19:04 +00002080{
2081#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002082 if (session->peer_cert != NULL) {
2083 mbedtls_x509_crt_free(session->peer_cert);
2084 mbedtls_free(session->peer_cert);
Hanno Beckerb9d44792019-02-08 07:19:04 +00002085 session->peer_cert = NULL;
2086 }
2087#else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002088 if (session->peer_cert_digest != NULL) {
Hanno Beckerb9d44792019-02-08 07:19:04 +00002089 /* Zeroization is not necessary. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002090 mbedtls_free(session->peer_cert_digest);
Hanno Beckerb9d44792019-02-08 07:19:04 +00002091 session->peer_cert_digest = NULL;
2092 session->peer_cert_digest_type = MBEDTLS_MD_NONE;
2093 session->peer_cert_digest_len = 0;
2094 }
2095#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
2096}
2097#endif /* MBEDTLS_X509_CRT_PARSE_C */
2098
Paul Bakker5121ce52009-01-03 21:22:43 +00002099/*
2100 * Handshake functions
2101 */
Gilles Peskineeccd8882020-03-10 12:19:08 +01002102#if !defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
Gilles Peskinef9828522017-05-03 12:28:43 +02002103/* No certificate support -> dummy functions */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002104int mbedtls_ssl_write_certificate(mbedtls_ssl_context *ssl)
Paul Bakker5121ce52009-01-03 21:22:43 +00002105{
Hanno Beckere694c3e2017-12-27 21:34:08 +00002106 const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
2107 ssl->handshake->ciphersuite_info;
Paul Bakker5121ce52009-01-03 21:22:43 +00002108
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002109 MBEDTLS_SSL_DEBUG_MSG(2, ("=> write certificate"));
Paul Bakker5121ce52009-01-03 21:22:43 +00002110
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002111 if (!mbedtls_ssl_ciphersuite_uses_srv_cert(ciphersuite_info)) {
2112 MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip write certificate"));
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02002113 ssl->state++;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002114 return 0;
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02002115 }
2116
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002117 MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
2118 return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002119}
2120
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002121int mbedtls_ssl_parse_certificate(mbedtls_ssl_context *ssl)
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002122{
Hanno Beckere694c3e2017-12-27 21:34:08 +00002123 const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
2124 ssl->handshake->ciphersuite_info;
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002125
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002126 MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse certificate"));
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002127
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002128 if (!mbedtls_ssl_ciphersuite_uses_srv_cert(ciphersuite_info)) {
2129 MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip parse certificate"));
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002130 ssl->state++;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002131 return 0;
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002132 }
2133
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002134 MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
2135 return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002136}
Gilles Peskinef9828522017-05-03 12:28:43 +02002137
Gilles Peskineeccd8882020-03-10 12:19:08 +01002138#else /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
Gilles Peskinef9828522017-05-03 12:28:43 +02002139/* Some certificate support -> implement write and parse */
2140
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002141int mbedtls_ssl_write_certificate(mbedtls_ssl_context *ssl)
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002142{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002143 int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002144 size_t i, n;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002145 const mbedtls_x509_crt *crt;
Hanno Beckere694c3e2017-12-27 21:34:08 +00002146 const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
2147 ssl->handshake->ciphersuite_info;
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002148
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002149 MBEDTLS_SSL_DEBUG_MSG(2, ("=> write certificate"));
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002150
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002151 if (!mbedtls_ssl_ciphersuite_uses_srv_cert(ciphersuite_info)) {
2152 MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip write certificate"));
Johan Pascal4f099262020-09-22 10:59:26 +02002153 ssl->state++;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002154 return 0;
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002155 }
2156
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002157#if defined(MBEDTLS_SSL_CLI_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002158 if (ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT) {
2159 if (ssl->client_auth == 0) {
2160 MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip write certificate"));
Paul Bakker5121ce52009-01-03 21:22:43 +00002161 ssl->state++;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002162 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +00002163 }
2164
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002165#if defined(MBEDTLS_SSL_PROTO_SSL3)
Paul Bakker5121ce52009-01-03 21:22:43 +00002166 /*
2167 * If using SSLv3 and got no cert, send an Alert message
2168 * (otherwise an empty Certificate message will be sent).
2169 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002170 if (mbedtls_ssl_own_cert(ssl) == NULL &&
2171 ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0) {
Paul Bakker5121ce52009-01-03 21:22:43 +00002172 ssl->out_msglen = 2;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002173 ssl->out_msgtype = MBEDTLS_SSL_MSG_ALERT;
2174 ssl->out_msg[0] = MBEDTLS_SSL_ALERT_LEVEL_WARNING;
2175 ssl->out_msg[1] = MBEDTLS_SSL_ALERT_MSG_NO_CERT;
Paul Bakker5121ce52009-01-03 21:22:43 +00002176
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002177 MBEDTLS_SSL_DEBUG_MSG(2, ("got no certificate to send"));
Paul Bakker5121ce52009-01-03 21:22:43 +00002178 goto write_msg;
2179 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002180#endif /* MBEDTLS_SSL_PROTO_SSL3 */
Paul Bakker5121ce52009-01-03 21:22:43 +00002181 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002182#endif /* MBEDTLS_SSL_CLI_C */
2183#if defined(MBEDTLS_SSL_SRV_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002184 if (ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER) {
2185 if (mbedtls_ssl_own_cert(ssl) == NULL) {
2186 MBEDTLS_SSL_DEBUG_MSG(1, ("got no certificate to send"));
2187 return MBEDTLS_ERR_SSL_CERTIFICATE_REQUIRED;
Paul Bakker5121ce52009-01-03 21:22:43 +00002188 }
2189 }
Manuel Pégourié-Gonnardd16d1cb2014-11-20 18:15:05 +01002190#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002191
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002192 MBEDTLS_SSL_DEBUG_CRT(3, "own certificate", mbedtls_ssl_own_cert(ssl));
Paul Bakker5121ce52009-01-03 21:22:43 +00002193
2194 /*
2195 * 0 . 0 handshake type
2196 * 1 . 3 handshake length
2197 * 4 . 6 length of all certs
2198 * 7 . 9 length of cert. 1
2199 * 10 . n-1 peer certificate
2200 * n . n+2 length of cert. 2
2201 * n+3 . ... upper level cert, etc.
2202 */
2203 i = 7;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002204 crt = mbedtls_ssl_own_cert(ssl);
Paul Bakker5121ce52009-01-03 21:22:43 +00002205
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002206 while (crt != NULL) {
Paul Bakker5121ce52009-01-03 21:22:43 +00002207 n = crt->raw.len;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002208 if (n > MBEDTLS_SSL_OUT_CONTENT_LEN - 3 - i) {
2209 MBEDTLS_SSL_DEBUG_MSG(1, ("certificate too large, %" MBEDTLS_PRINTF_SIZET
2210 " > %" MBEDTLS_PRINTF_SIZET,
2211 i + 3 + n, (size_t) MBEDTLS_SSL_OUT_CONTENT_LEN));
2212 return MBEDTLS_ERR_SSL_CERTIFICATE_TOO_LARGE;
Paul Bakker5121ce52009-01-03 21:22:43 +00002213 }
2214
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002215 ssl->out_msg[i] = MBEDTLS_BYTE_2(n);
2216 ssl->out_msg[i + 1] = MBEDTLS_BYTE_1(n);
2217 ssl->out_msg[i + 2] = MBEDTLS_BYTE_0(n);
Paul Bakker5121ce52009-01-03 21:22:43 +00002218
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002219 i += 3; memcpy(ssl->out_msg + i, crt->raw.p, n);
Paul Bakker5121ce52009-01-03 21:22:43 +00002220 i += n; crt = crt->next;
2221 }
2222
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002223 ssl->out_msg[4] = MBEDTLS_BYTE_2(i - 7);
2224 ssl->out_msg[5] = MBEDTLS_BYTE_1(i - 7);
2225 ssl->out_msg[6] = MBEDTLS_BYTE_0(i - 7);
Paul Bakker5121ce52009-01-03 21:22:43 +00002226
2227 ssl->out_msglen = i;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002228 ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
2229 ssl->out_msg[0] = MBEDTLS_SSL_HS_CERTIFICATE;
Paul Bakker5121ce52009-01-03 21:22:43 +00002230
Manuel Pégourié-Gonnardcf141ca2015-05-20 10:35:51 +02002231#if defined(MBEDTLS_SSL_PROTO_SSL3) && defined(MBEDTLS_SSL_CLI_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00002232write_msg:
Paul Bakkerd2f068e2013-08-27 21:19:20 +02002233#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002234
2235 ssl->state++;
2236
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002237 if ((ret = mbedtls_ssl_write_handshake_msg(ssl)) != 0) {
2238 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_handshake_msg", ret);
2239 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00002240 }
2241
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002242 MBEDTLS_SSL_DEBUG_MSG(2, ("<= write certificate"));
Paul Bakker5121ce52009-01-03 21:22:43 +00002243
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002244 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00002245}
2246
Hanno Becker84879e32019-01-31 07:44:03 +00002247#if defined(MBEDTLS_SSL_RENEGOTIATION) && defined(MBEDTLS_SSL_CLI_C)
Hanno Becker177475a2019-02-05 17:02:46 +00002248
2249#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +02002250MBEDTLS_CHECK_RETURN_CRITICAL
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002251static int ssl_check_peer_crt_unchanged(mbedtls_ssl_context *ssl,
2252 unsigned char *crt_buf,
2253 size_t crt_buf_len)
Hanno Beckerdef9bdc2019-01-30 14:46:46 +00002254{
2255 mbedtls_x509_crt const * const peer_crt = ssl->session->peer_cert;
2256
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002257 if (peer_crt == NULL) {
2258 return -1;
2259 }
Hanno Beckerdef9bdc2019-01-30 14:46:46 +00002260
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002261 if (peer_crt->raw.len != crt_buf_len) {
2262 return -1;
2263 }
Hanno Beckerdef9bdc2019-01-30 14:46:46 +00002264
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002265 return memcmp(peer_crt->raw.p, crt_buf, peer_crt->raw.len);
Hanno Beckerdef9bdc2019-01-30 14:46:46 +00002266}
Hanno Becker177475a2019-02-05 17:02:46 +00002267#else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +02002268MBEDTLS_CHECK_RETURN_CRITICAL
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002269static int ssl_check_peer_crt_unchanged(mbedtls_ssl_context *ssl,
2270 unsigned char *crt_buf,
2271 size_t crt_buf_len)
Hanno Becker177475a2019-02-05 17:02:46 +00002272{
Janos Follath865b3eb2019-12-16 11:46:15 +00002273 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Hanno Becker177475a2019-02-05 17:02:46 +00002274 unsigned char const * const peer_cert_digest =
2275 ssl->session->peer_cert_digest;
2276 mbedtls_md_type_t const peer_cert_digest_type =
2277 ssl->session->peer_cert_digest_type;
2278 mbedtls_md_info_t const * const digest_info =
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002279 mbedtls_md_info_from_type(peer_cert_digest_type);
Hanno Becker177475a2019-02-05 17:02:46 +00002280 unsigned char tmp_digest[MBEDTLS_SSL_PEER_CERT_DIGEST_MAX_LEN];
2281 size_t digest_len;
2282
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002283 if (peer_cert_digest == NULL || digest_info == NULL) {
2284 return -1;
2285 }
Hanno Becker177475a2019-02-05 17:02:46 +00002286
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002287 digest_len = mbedtls_md_get_size(digest_info);
2288 if (digest_len > MBEDTLS_SSL_PEER_CERT_DIGEST_MAX_LEN) {
2289 return -1;
2290 }
Hanno Becker177475a2019-02-05 17:02:46 +00002291
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002292 ret = mbedtls_md(digest_info, crt_buf, crt_buf_len, tmp_digest);
2293 if (ret != 0) {
2294 return -1;
2295 }
Hanno Becker177475a2019-02-05 17:02:46 +00002296
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002297 return memcmp(tmp_digest, peer_cert_digest, digest_len);
Hanno Becker177475a2019-02-05 17:02:46 +00002298}
2299#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
Hanno Becker84879e32019-01-31 07:44:03 +00002300#endif /* MBEDTLS_SSL_RENEGOTIATION && MBEDTLS_SSL_CLI_C */
Hanno Beckerdef9bdc2019-01-30 14:46:46 +00002301
Manuel Pégourié-Gonnardfed37ed2017-08-15 13:27:41 +02002302/*
2303 * Once the certificate message is read, parse it into a cert chain and
2304 * perform basic checks, but leave actual verification to the caller
2305 */
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +02002306MBEDTLS_CHECK_RETURN_CRITICAL
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002307static int ssl_parse_certificate_chain(mbedtls_ssl_context *ssl,
2308 mbedtls_x509_crt *chain)
Paul Bakker5121ce52009-01-03 21:22:43 +00002309{
Janos Follath865b3eb2019-12-16 11:46:15 +00002310 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Hanno Beckerc7bd7802019-02-05 15:37:23 +00002311#if defined(MBEDTLS_SSL_RENEGOTIATION) && defined(MBEDTLS_SSL_CLI_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002312 int crt_cnt = 0;
Hanno Beckerc7bd7802019-02-05 15:37:23 +00002313#endif
Paul Bakker23986e52011-04-24 08:57:21 +00002314 size_t i, n;
Gilles Peskine064a85c2017-05-10 10:46:40 +02002315 uint8_t alert;
Paul Bakker5121ce52009-01-03 21:22:43 +00002316
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002317 if (ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE) {
2318 MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate message"));
2319 mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
2320 MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE);
2321 return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
Paul Bakker5121ce52009-01-03 21:22:43 +00002322 }
2323
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002324 if (ssl->in_msg[0] != MBEDTLS_SSL_HS_CERTIFICATE ||
2325 ssl->in_hslen < mbedtls_ssl_hs_hdr_len(ssl) + 3 + 3) {
2326 MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate message"));
2327 mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
2328 MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
2329 return MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE;
Paul Bakker5121ce52009-01-03 21:22:43 +00002330 }
2331
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002332 i = mbedtls_ssl_hs_hdr_len(ssl);
Manuel Pégourié-Gonnardf49a7da2014-09-10 13:30:43 +00002333
Paul Bakker5121ce52009-01-03 21:22:43 +00002334 /*
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002335 * Same message structure as in mbedtls_ssl_write_certificate()
Paul Bakker5121ce52009-01-03 21:22:43 +00002336 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002337 n = (ssl->in_msg[i+1] << 8) | ssl->in_msg[i+2];
Paul Bakker5121ce52009-01-03 21:22:43 +00002338
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002339 if (ssl->in_msg[i] != 0 ||
2340 ssl->in_hslen != n + 3 + mbedtls_ssl_hs_hdr_len(ssl)) {
2341 MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate message"));
2342 mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
2343 MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
2344 return MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE;
Paul Bakker5121ce52009-01-03 21:22:43 +00002345 }
2346
Hanno Beckerdef9bdc2019-01-30 14:46:46 +00002347 /* Make &ssl->in_msg[i] point to the beginning of the CRT chain. */
2348 i += 3;
2349
Hanno Beckerdef9bdc2019-01-30 14:46:46 +00002350 /* Iterate through and parse the CRTs in the provided chain. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002351 while (i < ssl->in_hslen) {
Hanno Beckerdef9bdc2019-01-30 14:46:46 +00002352 /* Check that there's room for the next CRT's length fields. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002353 if (i + 3 > ssl->in_hslen) {
2354 MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate message"));
2355 mbedtls_ssl_send_alert_message(ssl,
2356 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
2357 MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
2358 return MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE;
Philippe Antoine747fd532018-05-30 09:13:21 +02002359 }
Hanno Beckerdef9bdc2019-01-30 14:46:46 +00002360 /* In theory, the CRT can be up to 2**24 Bytes, but we don't support
2361 * anything beyond 2**16 ~ 64K. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002362 if (ssl->in_msg[i] != 0) {
2363 MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate message"));
2364 mbedtls_ssl_send_alert_message(ssl,
2365 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
2366 MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
2367 return MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE;
Paul Bakker5121ce52009-01-03 21:22:43 +00002368 }
2369
Hanno Beckerdef9bdc2019-01-30 14:46:46 +00002370 /* Read length of the next CRT in the chain. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002371 n = ((unsigned int) ssl->in_msg[i + 1] << 8)
Paul Bakker5121ce52009-01-03 21:22:43 +00002372 | (unsigned int) ssl->in_msg[i + 2];
2373 i += 3;
2374
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002375 if (n < 128 || i + n > ssl->in_hslen) {
2376 MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate message"));
2377 mbedtls_ssl_send_alert_message(ssl,
2378 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
2379 MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
2380 return MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE;
Paul Bakker5121ce52009-01-03 21:22:43 +00002381 }
2382
Hanno Beckerdef9bdc2019-01-30 14:46:46 +00002383 /* Check if we're handling the first CRT in the chain. */
Hanno Beckerc7bd7802019-02-05 15:37:23 +00002384#if defined(MBEDTLS_SSL_RENEGOTIATION) && defined(MBEDTLS_SSL_CLI_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002385 if (crt_cnt++ == 0 &&
Hanno Beckerc7bd7802019-02-05 15:37:23 +00002386 ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT &&
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002387 ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS) {
Hanno Becker46f34d02019-02-08 14:00:04 +00002388 /* During client-side renegotiation, check that the server's
2389 * end-CRTs hasn't changed compared to the initial handshake,
2390 * mitigating the triple handshake attack. On success, reuse
2391 * the original end-CRT instead of parsing it again. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002392 MBEDTLS_SSL_DEBUG_MSG(3, ("Check that peer CRT hasn't changed during renegotiation"));
2393 if (ssl_check_peer_crt_unchanged(ssl,
2394 &ssl->in_msg[i],
2395 n) != 0) {
2396 MBEDTLS_SSL_DEBUG_MSG(1, ("new server cert during renegotiation"));
2397 mbedtls_ssl_send_alert_message(ssl,
2398 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
2399 MBEDTLS_SSL_ALERT_MSG_ACCESS_DENIED);
2400 return MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE;
Hanno Beckerdef9bdc2019-01-30 14:46:46 +00002401 }
Hanno Beckerc7bd7802019-02-05 15:37:23 +00002402
2403 /* Now we can safely free the original chain. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002404 ssl_clear_peer_cert(ssl->session);
Hanno Beckerc7bd7802019-02-05 15:37:23 +00002405 }
Hanno Beckerdef9bdc2019-01-30 14:46:46 +00002406#endif /* MBEDTLS_SSL_RENEGOTIATION && MBEDTLS_SSL_CLI_C */
2407
Hanno Beckerdef9bdc2019-01-30 14:46:46 +00002408 /* Parse the next certificate in the chain. */
Hanno Becker0056eab2019-02-08 14:39:16 +00002409#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002410 ret = mbedtls_x509_crt_parse_der(chain, ssl->in_msg + i, n);
Hanno Becker0056eab2019-02-08 14:39:16 +00002411#else
Hanno Becker353a6f02019-02-26 11:51:34 +00002412 /* If we don't need to store the CRT chain permanently, parse
Hanno Becker0056eab2019-02-08 14:39:16 +00002413 * it in-place from the input buffer instead of making a copy. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002414 ret = mbedtls_x509_crt_parse_der_nocopy(chain, ssl->in_msg + i, n);
Hanno Becker0056eab2019-02-08 14:39:16 +00002415#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002416 switch (ret) {
Hanno Beckerdef9bdc2019-01-30 14:46:46 +00002417 case 0: /*ok*/
2418 case MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG + MBEDTLS_ERR_OID_NOT_FOUND:
2419 /* Ignore certificate with an unknown algorithm: maybe a
2420 prior certificate was already trusted. */
2421 break;
Gilles Peskine1cc8e342017-05-03 16:28:34 +02002422
Hanno Beckerdef9bdc2019-01-30 14:46:46 +00002423 case MBEDTLS_ERR_X509_ALLOC_FAILED:
2424 alert = MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR;
2425 goto crt_parse_der_failed;
Gilles Peskine1cc8e342017-05-03 16:28:34 +02002426
Hanno Beckerdef9bdc2019-01-30 14:46:46 +00002427 case MBEDTLS_ERR_X509_UNKNOWN_VERSION:
2428 alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
2429 goto crt_parse_der_failed;
Gilles Peskine1cc8e342017-05-03 16:28:34 +02002430
Hanno Beckerdef9bdc2019-01-30 14:46:46 +00002431 default:
2432 alert = MBEDTLS_SSL_ALERT_MSG_BAD_CERT;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002433crt_parse_der_failed:
2434 mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, alert);
2435 MBEDTLS_SSL_DEBUG_RET(1, " mbedtls_x509_crt_parse_der", ret);
2436 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00002437 }
2438
2439 i += n;
2440 }
2441
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002442 MBEDTLS_SSL_DEBUG_CRT(3, "peer certificate", chain);
2443 return 0;
Manuel Pégourié-Gonnardfed37ed2017-08-15 13:27:41 +02002444}
2445
Hanno Becker4a55f632019-02-05 12:49:06 +00002446#if defined(MBEDTLS_SSL_SRV_C)
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +02002447MBEDTLS_CHECK_RETURN_CRITICAL
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002448static int ssl_srv_check_client_no_crt_notification(mbedtls_ssl_context *ssl)
Hanno Becker4a55f632019-02-05 12:49:06 +00002449{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002450 if (ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT) {
2451 return -1;
2452 }
Hanno Becker4a55f632019-02-05 12:49:06 +00002453
2454#if defined(MBEDTLS_SSL_PROTO_SSL3)
2455 /*
2456 * Check if the client sent an empty certificate
2457 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002458 if (ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0) {
2459 if (ssl->in_msglen == 2 &&
Hanno Becker4a55f632019-02-05 12:49:06 +00002460 ssl->in_msgtype == MBEDTLS_SSL_MSG_ALERT &&
2461 ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_WARNING &&
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002462 ssl->in_msg[1] == MBEDTLS_SSL_ALERT_MSG_NO_CERT) {
2463 MBEDTLS_SSL_DEBUG_MSG(1, ("SSLv3 client has no certificate"));
2464 return 0;
Hanno Becker4a55f632019-02-05 12:49:06 +00002465 }
2466
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002467 return -1;
Hanno Becker4a55f632019-02-05 12:49:06 +00002468 }
2469#endif /* MBEDTLS_SSL_PROTO_SSL3 */
2470
2471#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
2472 defined(MBEDTLS_SSL_PROTO_TLS1_2)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002473 if (ssl->in_hslen == 3 + mbedtls_ssl_hs_hdr_len(ssl) &&
Hanno Becker4a55f632019-02-05 12:49:06 +00002474 ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
2475 ssl->in_msg[0] == MBEDTLS_SSL_HS_CERTIFICATE &&
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002476 memcmp(ssl->in_msg + mbedtls_ssl_hs_hdr_len(ssl), "\0\0\0", 3) == 0) {
2477 MBEDTLS_SSL_DEBUG_MSG(1, ("TLSv1 client has no certificate"));
2478 return 0;
Hanno Becker4a55f632019-02-05 12:49:06 +00002479 }
2480
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002481 return -1;
Hanno Becker4a55f632019-02-05 12:49:06 +00002482#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \
2483 MBEDTLS_SSL_PROTO_TLS1_2 */
2484}
2485#endif /* MBEDTLS_SSL_SRV_C */
2486
Hanno Becker28f2fcd2019-02-07 10:11:07 +00002487/* Check if a certificate message is expected.
2488 * Return either
2489 * - SSL_CERTIFICATE_EXPECTED, or
2490 * - SSL_CERTIFICATE_SKIP
2491 * indicating whether a Certificate message is expected or not.
2492 */
2493#define SSL_CERTIFICATE_EXPECTED 0
2494#define SSL_CERTIFICATE_SKIP 1
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +02002495MBEDTLS_CHECK_RETURN_CRITICAL
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002496static int ssl_parse_certificate_coordinate(mbedtls_ssl_context *ssl,
2497 int authmode)
Hanno Becker28f2fcd2019-02-07 10:11:07 +00002498{
2499 const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
Hanno Beckere694c3e2017-12-27 21:34:08 +00002500 ssl->handshake->ciphersuite_info;
Hanno Becker28f2fcd2019-02-07 10:11:07 +00002501
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002502 if (!mbedtls_ssl_ciphersuite_uses_srv_cert(ciphersuite_info)) {
2503 return SSL_CERTIFICATE_SKIP;
2504 }
Hanno Becker28f2fcd2019-02-07 10:11:07 +00002505
2506#if defined(MBEDTLS_SSL_SRV_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002507 if (ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER) {
2508 if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK) {
2509 return SSL_CERTIFICATE_SKIP;
2510 }
Hanno Becker28f2fcd2019-02-07 10:11:07 +00002511
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002512 if (authmode == MBEDTLS_SSL_VERIFY_NONE) {
Hanno Becker28f2fcd2019-02-07 10:11:07 +00002513 ssl->session_negotiate->verify_result =
2514 MBEDTLS_X509_BADCERT_SKIP_VERIFY;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002515 return SSL_CERTIFICATE_SKIP;
Hanno Becker28f2fcd2019-02-07 10:11:07 +00002516 }
2517 }
Hanno Becker84d9d272019-03-01 08:10:46 +00002518#else
2519 ((void) authmode);
Hanno Becker28f2fcd2019-02-07 10:11:07 +00002520#endif /* MBEDTLS_SSL_SRV_C */
2521
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002522 return SSL_CERTIFICATE_EXPECTED;
Hanno Becker28f2fcd2019-02-07 10:11:07 +00002523}
2524
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +02002525MBEDTLS_CHECK_RETURN_CRITICAL
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002526static int ssl_parse_certificate_verify(mbedtls_ssl_context *ssl,
2527 int authmode,
2528 mbedtls_x509_crt *chain,
2529 void *rs_ctx)
Manuel Pégourié-Gonnardfed37ed2017-08-15 13:27:41 +02002530{
Hanno Becker6bdfab22019-02-05 13:11:17 +00002531 int ret = 0;
Hanno Becker28f2fcd2019-02-07 10:11:07 +00002532 const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
Hanno Beckere694c3e2017-12-27 21:34:08 +00002533 ssl->handshake->ciphersuite_info;
Hanno Beckerafd0b0a2019-03-27 16:55:01 +00002534 int have_ca_chain = 0;
Hanno Becker68636192019-02-05 14:36:34 +00002535
Hanno Becker8927c832019-04-03 12:52:50 +01002536 int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *);
2537 void *p_vrfy;
2538
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002539 if (authmode == MBEDTLS_SSL_VERIFY_NONE) {
2540 return 0;
2541 }
Hanno Becker68636192019-02-05 14:36:34 +00002542
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002543 if (ssl->f_vrfy != NULL) {
2544 MBEDTLS_SSL_DEBUG_MSG(3, ("Use context-specific verification callback"));
Hanno Becker8927c832019-04-03 12:52:50 +01002545 f_vrfy = ssl->f_vrfy;
2546 p_vrfy = ssl->p_vrfy;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002547 } else {
2548 MBEDTLS_SSL_DEBUG_MSG(3, ("Use configuration-specific verification callback"));
Hanno Becker8927c832019-04-03 12:52:50 +01002549 f_vrfy = ssl->conf->f_vrfy;
2550 p_vrfy = ssl->conf->p_vrfy;
2551 }
2552
Hanno Becker68636192019-02-05 14:36:34 +00002553 /*
2554 * Main check: verify certificate
2555 */
Hanno Beckerafd0b0a2019-03-27 16:55:01 +00002556#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002557 if (ssl->conf->f_ca_cb != NULL) {
Hanno Beckerafd0b0a2019-03-27 16:55:01 +00002558 ((void) rs_ctx);
2559 have_ca_chain = 1;
2560
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002561 MBEDTLS_SSL_DEBUG_MSG(3, ("use CA callback for X.509 CRT verification"));
Jarno Lamsa9822c0d2019-04-01 16:59:48 +03002562 ret = mbedtls_x509_crt_verify_with_ca_cb(
Hanno Beckerafd0b0a2019-03-27 16:55:01 +00002563 chain,
2564 ssl->conf->f_ca_cb,
2565 ssl->conf->p_ca_cb,
2566 ssl->conf->cert_profile,
2567 ssl->hostname,
2568 &ssl->session_negotiate->verify_result,
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002569 f_vrfy, p_vrfy);
2570 } else
Hanno Beckerafd0b0a2019-03-27 16:55:01 +00002571#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */
2572 {
2573 mbedtls_x509_crt *ca_chain;
2574 mbedtls_x509_crl *ca_crl;
2575
2576#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002577 if (ssl->handshake->sni_ca_chain != NULL) {
Hanno Beckerafd0b0a2019-03-27 16:55:01 +00002578 ca_chain = ssl->handshake->sni_ca_chain;
2579 ca_crl = ssl->handshake->sni_ca_crl;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002580 } else
Hanno Beckerafd0b0a2019-03-27 16:55:01 +00002581#endif
2582 {
2583 ca_chain = ssl->conf->ca_chain;
2584 ca_crl = ssl->conf->ca_crl;
2585 }
2586
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002587 if (ca_chain != NULL) {
Hanno Beckerafd0b0a2019-03-27 16:55:01 +00002588 have_ca_chain = 1;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002589 }
Hanno Beckerafd0b0a2019-03-27 16:55:01 +00002590
2591 ret = mbedtls_x509_crt_verify_restartable(
2592 chain,
2593 ca_chain, ca_crl,
2594 ssl->conf->cert_profile,
2595 ssl->hostname,
2596 &ssl->session_negotiate->verify_result,
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002597 f_vrfy, p_vrfy, rs_ctx);
Hanno Beckerafd0b0a2019-03-27 16:55:01 +00002598 }
Hanno Becker68636192019-02-05 14:36:34 +00002599
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002600 if (ret != 0) {
2601 MBEDTLS_SSL_DEBUG_RET(1, "x509_verify_cert", ret);
Hanno Becker68636192019-02-05 14:36:34 +00002602 }
2603
Gilles Peskineeccd8882020-03-10 12:19:08 +01002604#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002605 if (ret == MBEDTLS_ERR_ECP_IN_PROGRESS) {
2606 return MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS;
2607 }
Hanno Becker68636192019-02-05 14:36:34 +00002608#endif
2609
2610 /*
2611 * Secondary checks: always done, but change 'ret' only if it was 0
2612 */
2613
2614#if defined(MBEDTLS_ECP_C)
2615 {
2616 const mbedtls_pk_context *pk = &chain->pk;
2617
Manuel Pégourié-Gonnard06e1fcd2022-06-16 10:48:06 +02002618 /* If certificate uses an EC key, make sure the curve is OK.
2619 * This is a public key, so it can't be opaque, so can_do() is a good
2620 * enough check to ensure pk_ec() is safe to use here. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002621 if (mbedtls_pk_can_do(pk, MBEDTLS_PK_ECKEY) &&
2622 mbedtls_ssl_check_curve(ssl, mbedtls_pk_ec(*pk)->grp.id) != 0) {
Hanno Becker68636192019-02-05 14:36:34 +00002623 ssl->session_negotiate->verify_result |= MBEDTLS_X509_BADCERT_BAD_KEY;
2624
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002625 MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate (EC key curve)"));
2626 if (ret == 0) {
Hanno Becker68636192019-02-05 14:36:34 +00002627 ret = MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002628 }
Hanno Becker68636192019-02-05 14:36:34 +00002629 }
2630 }
2631#endif /* MBEDTLS_ECP_C */
2632
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002633 if (mbedtls_ssl_check_cert_usage(chain,
2634 ciphersuite_info,
2635 !ssl->conf->endpoint,
2636 &ssl->session_negotiate->verify_result) != 0) {
2637 MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate (usage extensions)"));
2638 if (ret == 0) {
Hanno Becker68636192019-02-05 14:36:34 +00002639 ret = MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002640 }
Hanno Becker68636192019-02-05 14:36:34 +00002641 }
2642
2643 /* mbedtls_x509_crt_verify_with_profile is supposed to report a
2644 * verification failure through MBEDTLS_ERR_X509_CERT_VERIFY_FAILED,
2645 * with details encoded in the verification flags. All other kinds
2646 * of error codes, including those from the user provided f_vrfy
2647 * functions, are treated as fatal and lead to a failure of
2648 * ssl_parse_certificate even if verification was optional. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002649 if (authmode == MBEDTLS_SSL_VERIFY_OPTIONAL &&
2650 (ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED ||
2651 ret == MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE)) {
Hanno Becker68636192019-02-05 14:36:34 +00002652 ret = 0;
2653 }
2654
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002655 if (have_ca_chain == 0 && authmode == MBEDTLS_SSL_VERIFY_REQUIRED) {
2656 MBEDTLS_SSL_DEBUG_MSG(1, ("got no CA chain"));
Hanno Becker68636192019-02-05 14:36:34 +00002657 ret = MBEDTLS_ERR_SSL_CA_CHAIN_REQUIRED;
2658 }
2659
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002660 if (ret != 0) {
Hanno Becker68636192019-02-05 14:36:34 +00002661 uint8_t alert;
2662
2663 /* The certificate may have been rejected for several reasons.
2664 Pick one and send the corresponding alert. Which alert to send
2665 may be a subject of debate in some cases. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002666 if (ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_OTHER) {
Hanno Becker68636192019-02-05 14:36:34 +00002667 alert = MBEDTLS_SSL_ALERT_MSG_ACCESS_DENIED;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002668 } else if (ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_CN_MISMATCH) {
Hanno Becker68636192019-02-05 14:36:34 +00002669 alert = MBEDTLS_SSL_ALERT_MSG_BAD_CERT;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002670 } else if (ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_KEY_USAGE) {
Hanno Becker68636192019-02-05 14:36:34 +00002671 alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002672 } else if (ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_EXT_KEY_USAGE) {
Hanno Becker68636192019-02-05 14:36:34 +00002673 alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002674 } else if (ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_NS_CERT_TYPE) {
Hanno Becker68636192019-02-05 14:36:34 +00002675 alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002676 } else if (ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_BAD_PK) {
Hanno Becker68636192019-02-05 14:36:34 +00002677 alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002678 } else if (ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_BAD_KEY) {
Hanno Becker68636192019-02-05 14:36:34 +00002679 alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002680 } else if (ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_EXPIRED) {
Hanno Becker68636192019-02-05 14:36:34 +00002681 alert = MBEDTLS_SSL_ALERT_MSG_CERT_EXPIRED;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002682 } else if (ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_REVOKED) {
Hanno Becker68636192019-02-05 14:36:34 +00002683 alert = MBEDTLS_SSL_ALERT_MSG_CERT_REVOKED;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002684 } else if (ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_NOT_TRUSTED) {
Hanno Becker68636192019-02-05 14:36:34 +00002685 alert = MBEDTLS_SSL_ALERT_MSG_UNKNOWN_CA;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002686 } else {
Hanno Becker68636192019-02-05 14:36:34 +00002687 alert = MBEDTLS_SSL_ALERT_MSG_CERT_UNKNOWN;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002688 }
2689 mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
2690 alert);
Hanno Becker68636192019-02-05 14:36:34 +00002691 }
2692
2693#if defined(MBEDTLS_DEBUG_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002694 if (ssl->session_negotiate->verify_result != 0) {
2695 MBEDTLS_SSL_DEBUG_MSG(3, ("! Certificate verification flags %08x",
2696 (unsigned int) ssl->session_negotiate->verify_result));
2697 } else {
2698 MBEDTLS_SSL_DEBUG_MSG(3, ("Certificate verification flags clear"));
Hanno Becker68636192019-02-05 14:36:34 +00002699 }
2700#endif /* MBEDTLS_DEBUG_C */
2701
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002702 return ret;
Hanno Becker68636192019-02-05 14:36:34 +00002703}
2704
Hanno Becker6b8fbab2019-02-08 14:59:05 +00002705#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +02002706MBEDTLS_CHECK_RETURN_CRITICAL
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002707static int ssl_remember_peer_crt_digest(mbedtls_ssl_context *ssl,
2708 unsigned char *start, size_t len)
Hanno Becker6b8fbab2019-02-08 14:59:05 +00002709{
Janos Follath865b3eb2019-12-16 11:46:15 +00002710 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Hanno Becker6b8fbab2019-02-08 14:59:05 +00002711 /* Remember digest of the peer's end-CRT. */
2712 ssl->session_negotiate->peer_cert_digest =
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002713 mbedtls_calloc(1, MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_LEN);
2714 if (ssl->session_negotiate->peer_cert_digest == NULL) {
2715 MBEDTLS_SSL_DEBUG_MSG(1, ("alloc(%d bytes) failed",
2716 MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_LEN));
2717 mbedtls_ssl_send_alert_message(ssl,
2718 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
2719 MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR);
Hanno Becker6b8fbab2019-02-08 14:59:05 +00002720
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002721 return MBEDTLS_ERR_SSL_ALLOC_FAILED;
Hanno Becker6b8fbab2019-02-08 14:59:05 +00002722 }
2723
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002724 ret = mbedtls_md(mbedtls_md_info_from_type(
2725 MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_TYPE),
2726 start, len,
2727 ssl->session_negotiate->peer_cert_digest);
Hanno Becker6b8fbab2019-02-08 14:59:05 +00002728
2729 ssl->session_negotiate->peer_cert_digest_type =
2730 MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_TYPE;
2731 ssl->session_negotiate->peer_cert_digest_len =
2732 MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_LEN;
2733
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002734 return ret;
Hanno Becker6b8fbab2019-02-08 14:59:05 +00002735}
2736
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +02002737MBEDTLS_CHECK_RETURN_CRITICAL
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002738static int ssl_remember_peer_pubkey(mbedtls_ssl_context *ssl,
2739 unsigned char *start, size_t len)
Hanno Becker6b8fbab2019-02-08 14:59:05 +00002740{
2741 unsigned char *end = start + len;
Janos Follath865b3eb2019-12-16 11:46:15 +00002742 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Hanno Becker6b8fbab2019-02-08 14:59:05 +00002743
2744 /* Make a copy of the peer's raw public key. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002745 mbedtls_pk_init(&ssl->handshake->peer_pubkey);
2746 ret = mbedtls_pk_parse_subpubkey(&start, end,
2747 &ssl->handshake->peer_pubkey);
2748 if (ret != 0) {
Hanno Becker6b8fbab2019-02-08 14:59:05 +00002749 /* We should have parsed the public key before. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002750 return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
Hanno Becker6b8fbab2019-02-08 14:59:05 +00002751 }
2752
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002753 return 0;
Hanno Becker6b8fbab2019-02-08 14:59:05 +00002754}
2755#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
2756
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002757int mbedtls_ssl_parse_certificate(mbedtls_ssl_context *ssl)
Hanno Becker68636192019-02-05 14:36:34 +00002758{
2759 int ret = 0;
Hanno Becker28f2fcd2019-02-07 10:11:07 +00002760 int crt_expected;
Manuel Pégourié-Gonnardfed37ed2017-08-15 13:27:41 +02002761#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
2762 const int authmode = ssl->handshake->sni_authmode != MBEDTLS_SSL_VERIFY_UNSET
2763 ? ssl->handshake->sni_authmode
2764 : ssl->conf->authmode;
2765#else
Johan Pascal4f099262020-09-22 10:59:26 +02002766 const int authmode = ssl->conf->authmode;
Manuel Pégourié-Gonnardfed37ed2017-08-15 13:27:41 +02002767#endif
Manuel Pégourié-Gonnard3bf49c42017-08-15 13:47:06 +02002768 void *rs_ctx = NULL;
Hanno Becker3dad3112019-02-05 17:19:52 +00002769 mbedtls_x509_crt *chain = NULL;
Manuel Pégourié-Gonnardfed37ed2017-08-15 13:27:41 +02002770
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002771 MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse certificate"));
Manuel Pégourié-Gonnardfed37ed2017-08-15 13:27:41 +02002772
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002773 crt_expected = ssl_parse_certificate_coordinate(ssl, authmode);
2774 if (crt_expected == SSL_CERTIFICATE_SKIP) {
2775 MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip parse certificate"));
Hanno Becker6bdfab22019-02-05 13:11:17 +00002776 goto exit;
Manuel Pégourié-Gonnardfed37ed2017-08-15 13:27:41 +02002777 }
2778
Gilles Peskineeccd8882020-03-10 12:19:08 +01002779#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002780 if (ssl->handshake->ecrs_enabled &&
2781 ssl->handshake->ecrs_state == ssl_ecrs_crt_verify) {
Hanno Becker3dad3112019-02-05 17:19:52 +00002782 chain = ssl->handshake->ecrs_peer_cert;
2783 ssl->handshake->ecrs_peer_cert = NULL;
Manuel Pégourié-Gonnard3bf49c42017-08-15 13:47:06 +02002784 goto crt_verify;
2785 }
2786#endif
2787
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002788 if ((ret = mbedtls_ssl_read_record(ssl, 1)) != 0) {
Manuel Pégourié-Gonnardfed37ed2017-08-15 13:27:41 +02002789 /* mbedtls_ssl_read_record may have sent an alert already. We
2790 let it decide whether to alert. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002791 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_read_record", ret);
Hanno Becker3dad3112019-02-05 17:19:52 +00002792 goto exit;
Manuel Pégourié-Gonnardfed37ed2017-08-15 13:27:41 +02002793 }
2794
Hanno Becker4a55f632019-02-05 12:49:06 +00002795#if defined(MBEDTLS_SSL_SRV_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002796 if (ssl_srv_check_client_no_crt_notification(ssl) == 0) {
Hanno Becker4a55f632019-02-05 12:49:06 +00002797 ssl->session_negotiate->verify_result = MBEDTLS_X509_BADCERT_MISSING;
Hanno Becker4a55f632019-02-05 12:49:06 +00002798
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002799 if (authmode != MBEDTLS_SSL_VERIFY_OPTIONAL) {
Hanno Becker6bdfab22019-02-05 13:11:17 +00002800 ret = MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002801 }
Hanno Becker4a55f632019-02-05 12:49:06 +00002802
Hanno Becker6bdfab22019-02-05 13:11:17 +00002803 goto exit;
Hanno Becker4a55f632019-02-05 12:49:06 +00002804 }
2805#endif /* MBEDTLS_SSL_SRV_C */
2806
Hanno Beckerc7bd7802019-02-05 15:37:23 +00002807 /* Clear existing peer CRT structure in case we tried to
2808 * reuse a session but it failed, and allocate a new one. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002809 ssl_clear_peer_cert(ssl->session_negotiate);
Hanno Becker3dad3112019-02-05 17:19:52 +00002810
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002811 chain = mbedtls_calloc(1, sizeof(mbedtls_x509_crt));
2812 if (chain == NULL) {
2813 MBEDTLS_SSL_DEBUG_MSG(1, ("alloc(%" MBEDTLS_PRINTF_SIZET " bytes) failed",
2814 sizeof(mbedtls_x509_crt)));
2815 mbedtls_ssl_send_alert_message(ssl,
2816 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
2817 MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR);
Hanno Becker7a955a02019-02-05 13:08:01 +00002818
Hanno Becker3dad3112019-02-05 17:19:52 +00002819 ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
2820 goto exit;
2821 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002822 mbedtls_x509_crt_init(chain);
Hanno Becker3dad3112019-02-05 17:19:52 +00002823
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002824 ret = ssl_parse_certificate_chain(ssl, chain);
2825 if (ret != 0) {
Hanno Becker3dad3112019-02-05 17:19:52 +00002826 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002827 }
Manuel Pégourié-Gonnardfed37ed2017-08-15 13:27:41 +02002828
Gilles Peskineeccd8882020-03-10 12:19:08 +01002829#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002830 if (ssl->handshake->ecrs_enabled) {
Manuel Pégourié-Gonnard0b23f162017-08-24 12:08:33 +02002831 ssl->handshake->ecrs_state = ssl_ecrs_crt_verify;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002832 }
Manuel Pégourié-Gonnard3bf49c42017-08-15 13:47:06 +02002833
2834crt_verify:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002835 if (ssl->handshake->ecrs_enabled) {
Manuel Pégourié-Gonnard3bf49c42017-08-15 13:47:06 +02002836 rs_ctx = &ssl->handshake->ecrs_ctx;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002837 }
Manuel Pégourié-Gonnard3bf49c42017-08-15 13:47:06 +02002838#endif
2839
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002840 ret = ssl_parse_certificate_verify(ssl, authmode,
2841 chain, rs_ctx);
2842 if (ret != 0) {
Hanno Becker3dad3112019-02-05 17:19:52 +00002843 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002844 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002845
Hanno Becker6bbd94c2019-02-05 17:02:28 +00002846#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
Hanno Becker6bbd94c2019-02-05 17:02:28 +00002847 {
Hanno Becker6b8fbab2019-02-08 14:59:05 +00002848 unsigned char *crt_start, *pk_start;
2849 size_t crt_len, pk_len;
Hanno Becker3dad3112019-02-05 17:19:52 +00002850
Hanno Becker6b8fbab2019-02-08 14:59:05 +00002851 /* We parse the CRT chain without copying, so
2852 * these pointers point into the input buffer,
2853 * and are hence still valid after freeing the
2854 * CRT chain. */
Hanno Becker6bbd94c2019-02-05 17:02:28 +00002855
Hanno Becker6b8fbab2019-02-08 14:59:05 +00002856 crt_start = chain->raw.p;
2857 crt_len = chain->raw.len;
Hanno Becker6bbd94c2019-02-05 17:02:28 +00002858
Hanno Becker6b8fbab2019-02-08 14:59:05 +00002859 pk_start = chain->pk_raw.p;
2860 pk_len = chain->pk_raw.len;
2861
2862 /* Free the CRT structures before computing
2863 * digest and copying the peer's public key. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002864 mbedtls_x509_crt_free(chain);
2865 mbedtls_free(chain);
Hanno Becker6b8fbab2019-02-08 14:59:05 +00002866 chain = NULL;
2867
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002868 ret = ssl_remember_peer_crt_digest(ssl, crt_start, crt_len);
2869 if (ret != 0) {
Hanno Beckera2747532019-02-06 16:19:04 +00002870 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002871 }
Hanno Becker6b8fbab2019-02-08 14:59:05 +00002872
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002873 ret = ssl_remember_peer_pubkey(ssl, pk_start, pk_len);
2874 if (ret != 0) {
Hanno Becker6b8fbab2019-02-08 14:59:05 +00002875 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002876 }
Hanno Beckera2747532019-02-06 16:19:04 +00002877 }
Hanno Becker6b8fbab2019-02-08 14:59:05 +00002878#else /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
2879 /* Pass ownership to session structure. */
Hanno Becker3dad3112019-02-05 17:19:52 +00002880 ssl->session_negotiate->peer_cert = chain;
2881 chain = NULL;
Hanno Becker6b8fbab2019-02-08 14:59:05 +00002882#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
Hanno Becker3dad3112019-02-05 17:19:52 +00002883
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002884 MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse certificate"));
Paul Bakker5121ce52009-01-03 21:22:43 +00002885
Hanno Becker6bdfab22019-02-05 13:11:17 +00002886exit:
2887
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002888 if (ret == 0) {
Hanno Becker3dad3112019-02-05 17:19:52 +00002889 ssl->state++;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002890 }
Hanno Becker3dad3112019-02-05 17:19:52 +00002891
Gilles Peskineeccd8882020-03-10 12:19:08 +01002892#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002893 if (ret == MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS) {
Hanno Becker3dad3112019-02-05 17:19:52 +00002894 ssl->handshake->ecrs_peer_cert = chain;
2895 chain = NULL;
2896 }
2897#endif
2898
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002899 if (chain != NULL) {
2900 mbedtls_x509_crt_free(chain);
2901 mbedtls_free(chain);
Hanno Becker3dad3112019-02-05 17:19:52 +00002902 }
2903
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002904 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00002905}
Gilles Peskineeccd8882020-03-10 12:19:08 +01002906#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
Paul Bakker5121ce52009-01-03 21:22:43 +00002907
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002908void mbedtls_ssl_optimize_checksum(mbedtls_ssl_context *ssl,
2909 const mbedtls_ssl_ciphersuite_t *ciphersuite_info)
Paul Bakker380da532012-04-18 16:10:25 +00002910{
Paul Bakkerfb08fd22013-08-27 15:06:26 +02002911 ((void) ciphersuite_info);
Paul Bakker769075d2012-11-24 11:26:46 +01002912
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002913#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
2914 defined(MBEDTLS_SSL_PROTO_TLS1_1)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002915 if (ssl->minor_ver < MBEDTLS_SSL_MINOR_VERSION_3) {
Paul Bakker48916f92012-09-16 19:57:18 +00002916 ssl->handshake->update_checksum = ssl_update_checksum_md5sha1;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002917 } else
Paul Bakkerd2f068e2013-08-27 21:19:20 +02002918#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002919#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
Gilles Peskined2d59372021-05-12 22:43:27 +02002920#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002921 if (ciphersuite_info->mac == MBEDTLS_MD_SHA384) {
Paul Bakkerd2f068e2013-08-27 21:19:20 +02002922 ssl->handshake->update_checksum = ssl_update_checksum_sha384;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002923 } else
Paul Bakkerd2f068e2013-08-27 21:19:20 +02002924#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002925#if defined(MBEDTLS_SHA256_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002926 if (ciphersuite_info->mac != MBEDTLS_MD_SHA384) {
Paul Bakker48916f92012-09-16 19:57:18 +00002927 ssl->handshake->update_checksum = ssl_update_checksum_sha256;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002928 } else
Paul Bakkerd2f068e2013-08-27 21:19:20 +02002929#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002930#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
Manuel Pégourié-Gonnard61edffe2014-04-11 17:07:31 +02002931 {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002932 MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
Paul Bakkerd2f068e2013-08-27 21:19:20 +02002933 return;
Manuel Pégourié-Gonnard61edffe2014-04-11 17:07:31 +02002934 }
Paul Bakker380da532012-04-18 16:10:25 +00002935}
Paul Bakkerf7abd422013-04-16 13:15:56 +02002936
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002937void mbedtls_ssl_reset_checksum(mbedtls_ssl_context *ssl)
Manuel Pégourié-Gonnard67427c02014-07-11 13:45:34 +02002938{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002939#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
2940 defined(MBEDTLS_SSL_PROTO_TLS1_1)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002941 mbedtls_md5_starts_ret(&ssl->handshake->fin_md5);
2942 mbedtls_sha1_starts_ret(&ssl->handshake->fin_sha1);
Manuel Pégourié-Gonnard67427c02014-07-11 13:45:34 +02002943#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002944#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
2945#if defined(MBEDTLS_SHA256_C)
Andrzej Kurekeb342242019-01-29 09:14:33 -05002946#if defined(MBEDTLS_USE_PSA_CRYPTO)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002947 psa_hash_abort(&ssl->handshake->fin_sha256_psa);
2948 psa_hash_setup(&ssl->handshake->fin_sha256_psa, PSA_ALG_SHA_256);
Andrzej Kurekeb342242019-01-29 09:14:33 -05002949#else
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002950 mbedtls_sha256_starts_ret(&ssl->handshake->fin_sha256, 0);
Manuel Pégourié-Gonnard67427c02014-07-11 13:45:34 +02002951#endif
Andrzej Kurekeb342242019-01-29 09:14:33 -05002952#endif
Gilles Peskined2d59372021-05-12 22:43:27 +02002953#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384)
Andrzej Kurekeb342242019-01-29 09:14:33 -05002954#if defined(MBEDTLS_USE_PSA_CRYPTO)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002955 psa_hash_abort(&ssl->handshake->fin_sha384_psa);
2956 psa_hash_setup(&ssl->handshake->fin_sha384_psa, PSA_ALG_SHA_384);
Andrzej Kurekeb342242019-01-29 09:14:33 -05002957#else
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002958 mbedtls_sha512_starts_ret(&ssl->handshake->fin_sha512, 1);
Manuel Pégourié-Gonnard67427c02014-07-11 13:45:34 +02002959#endif
Andrzej Kurekeb342242019-01-29 09:14:33 -05002960#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002961#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
Manuel Pégourié-Gonnard67427c02014-07-11 13:45:34 +02002962}
2963
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002964static void ssl_update_checksum_start(mbedtls_ssl_context *ssl,
2965 const unsigned char *buf, size_t len)
Paul Bakker380da532012-04-18 16:10:25 +00002966{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002967#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
2968 defined(MBEDTLS_SSL_PROTO_TLS1_1)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002969 mbedtls_md5_update_ret(&ssl->handshake->fin_md5, buf, len);
2970 mbedtls_sha1_update_ret(&ssl->handshake->fin_sha1, buf, len);
Paul Bakkerd2f068e2013-08-27 21:19:20 +02002971#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002972#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
2973#if defined(MBEDTLS_SHA256_C)
Andrzej Kurekeb342242019-01-29 09:14:33 -05002974#if defined(MBEDTLS_USE_PSA_CRYPTO)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002975 psa_hash_update(&ssl->handshake->fin_sha256_psa, buf, len);
Andrzej Kurekeb342242019-01-29 09:14:33 -05002976#else
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002977 mbedtls_sha256_update_ret(&ssl->handshake->fin_sha256, buf, len);
Paul Bakkerd2f068e2013-08-27 21:19:20 +02002978#endif
Andrzej Kurekeb342242019-01-29 09:14:33 -05002979#endif
Gilles Peskined2d59372021-05-12 22:43:27 +02002980#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384)
Andrzej Kurekeb342242019-01-29 09:14:33 -05002981#if defined(MBEDTLS_USE_PSA_CRYPTO)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002982 psa_hash_update(&ssl->handshake->fin_sha384_psa, buf, len);
Andrzej Kurekeb342242019-01-29 09:14:33 -05002983#else
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002984 mbedtls_sha512_update_ret(&ssl->handshake->fin_sha512, buf, len);
Paul Bakker769075d2012-11-24 11:26:46 +01002985#endif
Andrzej Kurekeb342242019-01-29 09:14:33 -05002986#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002987#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
Paul Bakker380da532012-04-18 16:10:25 +00002988}
2989
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002990#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
2991 defined(MBEDTLS_SSL_PROTO_TLS1_1)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002992static void ssl_update_checksum_md5sha1(mbedtls_ssl_context *ssl,
2993 const unsigned char *buf, size_t len)
Paul Bakker380da532012-04-18 16:10:25 +00002994{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002995 mbedtls_md5_update_ret(&ssl->handshake->fin_md5, buf, len);
2996 mbedtls_sha1_update_ret(&ssl->handshake->fin_sha1, buf, len);
Paul Bakker380da532012-04-18 16:10:25 +00002997}
Paul Bakkerd2f068e2013-08-27 21:19:20 +02002998#endif
Paul Bakker380da532012-04-18 16:10:25 +00002999
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003000#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
3001#if defined(MBEDTLS_SHA256_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003002static void ssl_update_checksum_sha256(mbedtls_ssl_context *ssl,
3003 const unsigned char *buf, size_t len)
Paul Bakker380da532012-04-18 16:10:25 +00003004{
Andrzej Kurekeb342242019-01-29 09:14:33 -05003005#if defined(MBEDTLS_USE_PSA_CRYPTO)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003006 psa_hash_update(&ssl->handshake->fin_sha256_psa, buf, len);
Andrzej Kurekeb342242019-01-29 09:14:33 -05003007#else
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003008 mbedtls_sha256_update_ret(&ssl->handshake->fin_sha256, buf, len);
Andrzej Kurekeb342242019-01-29 09:14:33 -05003009#endif
Paul Bakker380da532012-04-18 16:10:25 +00003010}
Paul Bakkerd2f068e2013-08-27 21:19:20 +02003011#endif
Paul Bakker380da532012-04-18 16:10:25 +00003012
Gilles Peskined2d59372021-05-12 22:43:27 +02003013#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003014static void ssl_update_checksum_sha384(mbedtls_ssl_context *ssl,
3015 const unsigned char *buf, size_t len)
Paul Bakker380da532012-04-18 16:10:25 +00003016{
Andrzej Kurekeb342242019-01-29 09:14:33 -05003017#if defined(MBEDTLS_USE_PSA_CRYPTO)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003018 psa_hash_update(&ssl->handshake->fin_sha384_psa, buf, len);
Andrzej Kurekeb342242019-01-29 09:14:33 -05003019#else
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003020 mbedtls_sha512_update_ret(&ssl->handshake->fin_sha512, buf, len);
Andrzej Kurekeb342242019-01-29 09:14:33 -05003021#endif
Paul Bakker380da532012-04-18 16:10:25 +00003022}
Paul Bakker769075d2012-11-24 11:26:46 +01003023#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003024#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
Paul Bakker380da532012-04-18 16:10:25 +00003025
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003026#if defined(MBEDTLS_SSL_PROTO_SSL3)
Paul Bakker1ef83d62012-04-11 12:09:53 +00003027static void ssl_calc_finished_ssl(
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003028 mbedtls_ssl_context *ssl, unsigned char *buf, int from)
Paul Bakker5121ce52009-01-03 21:22:43 +00003029{
Paul Bakker3c2122f2013-06-24 19:03:14 +02003030 const char *sender;
Manuel Pégourié-Gonnardc0bf01e2015-07-06 16:11:18 +02003031 mbedtls_md5_context md5;
3032 mbedtls_sha1_context sha1;
Paul Bakker1ef83d62012-04-11 12:09:53 +00003033
Paul Bakker5121ce52009-01-03 21:22:43 +00003034 unsigned char padbuf[48];
3035 unsigned char md5sum[16];
3036 unsigned char sha1sum[20];
3037
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003038 mbedtls_ssl_session *session = ssl->session_negotiate;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003039 if (!session) {
Paul Bakker48916f92012-09-16 19:57:18 +00003040 session = ssl->session;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003041 }
Paul Bakker48916f92012-09-16 19:57:18 +00003042
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003043 MBEDTLS_SSL_DEBUG_MSG(2, ("=> calc finished ssl"));
Paul Bakker1ef83d62012-04-11 12:09:53 +00003044
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003045 mbedtls_md5_init(&md5);
3046 mbedtls_sha1_init(&sha1);
Manuel Pégourié-Gonnard001f2b62015-07-06 16:21:13 +02003047
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003048 mbedtls_md5_clone(&md5, &ssl->handshake->fin_md5);
3049 mbedtls_sha1_clone(&sha1, &ssl->handshake->fin_sha1);
Paul Bakker5121ce52009-01-03 21:22:43 +00003050
3051 /*
3052 * SSLv3:
3053 * hash =
3054 * MD5( master + pad2 +
3055 * MD5( handshake + sender + master + pad1 ) )
3056 * + SHA1( master + pad2 +
3057 * SHA1( handshake + sender + master + pad1 ) )
Paul Bakker5121ce52009-01-03 21:22:43 +00003058 */
3059
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003060#if !defined(MBEDTLS_MD5_ALT)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003061 MBEDTLS_SSL_DEBUG_BUF(4, "finished md5 state", (unsigned char *)
3062 md5.state, sizeof(md5.state));
Paul Bakker90995b52013-06-24 19:20:35 +02003063#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003064
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003065#if !defined(MBEDTLS_SHA1_ALT)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003066 MBEDTLS_SSL_DEBUG_BUF(4, "finished sha1 state", (unsigned char *)
3067 sha1.state, sizeof(sha1.state));
Paul Bakker90995b52013-06-24 19:20:35 +02003068#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003069
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003070 sender = (from == MBEDTLS_SSL_IS_CLIENT) ? "CLNT"
Paul Bakker3c2122f2013-06-24 19:03:14 +02003071 : "SRVR";
Paul Bakker5121ce52009-01-03 21:22:43 +00003072
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003073 memset(padbuf, 0x36, 48);
Paul Bakker5121ce52009-01-03 21:22:43 +00003074
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003075 mbedtls_md5_update_ret(&md5, (const unsigned char *) sender, 4);
3076 mbedtls_md5_update_ret(&md5, session->master, 48);
3077 mbedtls_md5_update_ret(&md5, padbuf, 48);
3078 mbedtls_md5_finish_ret(&md5, md5sum);
Paul Bakker5121ce52009-01-03 21:22:43 +00003079
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003080 mbedtls_sha1_update_ret(&sha1, (const unsigned char *) sender, 4);
3081 mbedtls_sha1_update_ret(&sha1, session->master, 48);
3082 mbedtls_sha1_update_ret(&sha1, padbuf, 40);
3083 mbedtls_sha1_finish_ret(&sha1, sha1sum);
Paul Bakker5121ce52009-01-03 21:22:43 +00003084
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003085 memset(padbuf, 0x5C, 48);
Paul Bakker5121ce52009-01-03 21:22:43 +00003086
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003087 mbedtls_md5_starts_ret(&md5);
3088 mbedtls_md5_update_ret(&md5, session->master, 48);
3089 mbedtls_md5_update_ret(&md5, padbuf, 48);
3090 mbedtls_md5_update_ret(&md5, md5sum, 16);
3091 mbedtls_md5_finish_ret(&md5, buf);
Paul Bakker5121ce52009-01-03 21:22:43 +00003092
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003093 mbedtls_sha1_starts_ret(&sha1);
3094 mbedtls_sha1_update_ret(&sha1, session->master, 48);
3095 mbedtls_sha1_update_ret(&sha1, padbuf, 40);
3096 mbedtls_sha1_update_ret(&sha1, sha1sum, 20);
3097 mbedtls_sha1_finish_ret(&sha1, buf + 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00003098
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003099 MBEDTLS_SSL_DEBUG_BUF(3, "calc finished result", buf, 36);
Paul Bakker5121ce52009-01-03 21:22:43 +00003100
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003101 mbedtls_md5_free(&md5);
3102 mbedtls_sha1_free(&sha1);
Paul Bakker5121ce52009-01-03 21:22:43 +00003103
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003104 mbedtls_platform_zeroize(padbuf, sizeof(padbuf));
3105 mbedtls_platform_zeroize(md5sum, sizeof(md5sum));
3106 mbedtls_platform_zeroize(sha1sum, sizeof(sha1sum));
Paul Bakker5121ce52009-01-03 21:22:43 +00003107
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003108 MBEDTLS_SSL_DEBUG_MSG(2, ("<= calc finished"));
Paul Bakker5121ce52009-01-03 21:22:43 +00003109}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003110#endif /* MBEDTLS_SSL_PROTO_SSL3 */
Paul Bakker5121ce52009-01-03 21:22:43 +00003111
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003112#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1)
Paul Bakker1ef83d62012-04-11 12:09:53 +00003113static void ssl_calc_finished_tls(
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003114 mbedtls_ssl_context *ssl, unsigned char *buf, int from)
Paul Bakker5121ce52009-01-03 21:22:43 +00003115{
Paul Bakker1ef83d62012-04-11 12:09:53 +00003116 int len = 12;
Paul Bakker3c2122f2013-06-24 19:03:14 +02003117 const char *sender;
Manuel Pégourié-Gonnardc0bf01e2015-07-06 16:11:18 +02003118 mbedtls_md5_context md5;
3119 mbedtls_sha1_context sha1;
Paul Bakker1ef83d62012-04-11 12:09:53 +00003120 unsigned char padbuf[36];
Paul Bakker5121ce52009-01-03 21:22:43 +00003121
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003122 mbedtls_ssl_session *session = ssl->session_negotiate;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003123 if (!session) {
Paul Bakker48916f92012-09-16 19:57:18 +00003124 session = ssl->session;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003125 }
Paul Bakker48916f92012-09-16 19:57:18 +00003126
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003127 MBEDTLS_SSL_DEBUG_MSG(2, ("=> calc finished tls"));
Paul Bakker5121ce52009-01-03 21:22:43 +00003128
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003129 mbedtls_md5_init(&md5);
3130 mbedtls_sha1_init(&sha1);
Manuel Pégourié-Gonnard001f2b62015-07-06 16:21:13 +02003131
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003132 mbedtls_md5_clone(&md5, &ssl->handshake->fin_md5);
3133 mbedtls_sha1_clone(&sha1, &ssl->handshake->fin_sha1);
Paul Bakker5121ce52009-01-03 21:22:43 +00003134
Paul Bakker1ef83d62012-04-11 12:09:53 +00003135 /*
3136 * TLSv1:
3137 * hash = PRF( master, finished_label,
3138 * MD5( handshake ) + SHA1( handshake ) )[0..11]
3139 */
Paul Bakker5121ce52009-01-03 21:22:43 +00003140
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003141#if !defined(MBEDTLS_MD5_ALT)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003142 MBEDTLS_SSL_DEBUG_BUF(4, "finished md5 state", (unsigned char *)
3143 md5.state, sizeof(md5.state));
Paul Bakker90995b52013-06-24 19:20:35 +02003144#endif
Paul Bakker1ef83d62012-04-11 12:09:53 +00003145
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003146#if !defined(MBEDTLS_SHA1_ALT)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003147 MBEDTLS_SSL_DEBUG_BUF(4, "finished sha1 state", (unsigned char *)
3148 sha1.state, sizeof(sha1.state));
Paul Bakker90995b52013-06-24 19:20:35 +02003149#endif
Paul Bakker1ef83d62012-04-11 12:09:53 +00003150
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003151 sender = (from == MBEDTLS_SSL_IS_CLIENT)
Paul Bakker3c2122f2013-06-24 19:03:14 +02003152 ? "client finished"
3153 : "server finished";
Paul Bakker1ef83d62012-04-11 12:09:53 +00003154
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003155 mbedtls_md5_finish_ret(&md5, padbuf);
3156 mbedtls_sha1_finish_ret(&sha1, padbuf + 16);
Paul Bakker1ef83d62012-04-11 12:09:53 +00003157
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003158 ssl->handshake->tls_prf(session->master, 48, sender,
3159 padbuf, 36, buf, len);
Paul Bakker1ef83d62012-04-11 12:09:53 +00003160
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003161 MBEDTLS_SSL_DEBUG_BUF(3, "calc finished result", buf, len);
Paul Bakker1ef83d62012-04-11 12:09:53 +00003162
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003163 mbedtls_md5_free(&md5);
3164 mbedtls_sha1_free(&sha1);
Paul Bakker1ef83d62012-04-11 12:09:53 +00003165
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003166 mbedtls_platform_zeroize(padbuf, sizeof(padbuf));
Paul Bakker1ef83d62012-04-11 12:09:53 +00003167
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003168 MBEDTLS_SSL_DEBUG_MSG(2, ("<= calc finished"));
Paul Bakker1ef83d62012-04-11 12:09:53 +00003169}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003170#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 */
Paul Bakker1ef83d62012-04-11 12:09:53 +00003171
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003172#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
3173#if defined(MBEDTLS_SHA256_C)
Paul Bakkerca4ab492012-04-18 14:23:57 +00003174static void ssl_calc_finished_tls_sha256(
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003175 mbedtls_ssl_context *ssl, unsigned char *buf, int from)
Paul Bakker1ef83d62012-04-11 12:09:53 +00003176{
3177 int len = 12;
Paul Bakker3c2122f2013-06-24 19:03:14 +02003178 const char *sender;
Paul Bakker1ef83d62012-04-11 12:09:53 +00003179 unsigned char padbuf[32];
Andrzej Kurekeb342242019-01-29 09:14:33 -05003180#if defined(MBEDTLS_USE_PSA_CRYPTO)
3181 size_t hash_size;
Jaeden Amero34973232019-02-20 10:32:28 +00003182 psa_hash_operation_t sha256_psa = PSA_HASH_OPERATION_INIT;
Andrzej Kurekeb342242019-01-29 09:14:33 -05003183 psa_status_t status;
3184#else
3185 mbedtls_sha256_context sha256;
3186#endif
Paul Bakker1ef83d62012-04-11 12:09:53 +00003187
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003188 mbedtls_ssl_session *session = ssl->session_negotiate;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003189 if (!session) {
Paul Bakker48916f92012-09-16 19:57:18 +00003190 session = ssl->session;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003191 }
Paul Bakker48916f92012-09-16 19:57:18 +00003192
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003193 sender = (from == MBEDTLS_SSL_IS_CLIENT)
Andrzej Kurekeb342242019-01-29 09:14:33 -05003194 ? "client finished"
3195 : "server finished";
3196
3197#if defined(MBEDTLS_USE_PSA_CRYPTO)
3198 sha256_psa = psa_hash_operation_init();
3199
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003200 MBEDTLS_SSL_DEBUG_MSG(2, ("=> calc PSA finished tls sha256"));
Andrzej Kurekeb342242019-01-29 09:14:33 -05003201
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003202 status = psa_hash_clone(&ssl->handshake->fin_sha256_psa, &sha256_psa);
3203 if (status != PSA_SUCCESS) {
3204 MBEDTLS_SSL_DEBUG_MSG(2, ("PSA hash clone failed"));
Andrzej Kurekeb342242019-01-29 09:14:33 -05003205 return;
3206 }
3207
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003208 status = psa_hash_finish(&sha256_psa, padbuf, sizeof(padbuf), &hash_size);
3209 if (status != PSA_SUCCESS) {
3210 MBEDTLS_SSL_DEBUG_MSG(2, ("PSA hash finish failed"));
Andrzej Kurekeb342242019-01-29 09:14:33 -05003211 return;
3212 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003213 MBEDTLS_SSL_DEBUG_BUF(3, "PSA calculated padbuf", padbuf, 32);
Andrzej Kurekeb342242019-01-29 09:14:33 -05003214#else
3215
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003216 mbedtls_sha256_init(&sha256);
Manuel Pégourié-Gonnard001f2b62015-07-06 16:21:13 +02003217
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003218 MBEDTLS_SSL_DEBUG_MSG(2, ("=> calc finished tls sha256"));
Paul Bakker1ef83d62012-04-11 12:09:53 +00003219
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003220 mbedtls_sha256_clone(&sha256, &ssl->handshake->fin_sha256);
Paul Bakker1ef83d62012-04-11 12:09:53 +00003221
3222 /*
3223 * TLSv1.2:
3224 * hash = PRF( master, finished_label,
3225 * Hash( handshake ) )[0.11]
3226 */
3227
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003228#if !defined(MBEDTLS_SHA256_ALT)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003229 MBEDTLS_SSL_DEBUG_BUF(4, "finished sha2 state", (unsigned char *)
3230 sha256.state, sizeof(sha256.state));
Paul Bakker90995b52013-06-24 19:20:35 +02003231#endif
Paul Bakker1ef83d62012-04-11 12:09:53 +00003232
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003233 mbedtls_sha256_finish_ret(&sha256, padbuf);
3234 mbedtls_sha256_free(&sha256);
Andrzej Kurekeb342242019-01-29 09:14:33 -05003235#endif /* MBEDTLS_USE_PSA_CRYPTO */
Paul Bakker1ef83d62012-04-11 12:09:53 +00003236
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003237 ssl->handshake->tls_prf(session->master, 48, sender,
3238 padbuf, 32, buf, len);
Paul Bakker1ef83d62012-04-11 12:09:53 +00003239
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003240 MBEDTLS_SSL_DEBUG_BUF(3, "calc finished result", buf, len);
Paul Bakker1ef83d62012-04-11 12:09:53 +00003241
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003242 mbedtls_platform_zeroize(padbuf, sizeof(padbuf));
Paul Bakker1ef83d62012-04-11 12:09:53 +00003243
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003244 MBEDTLS_SSL_DEBUG_MSG(2, ("<= calc finished"));
Paul Bakker1ef83d62012-04-11 12:09:53 +00003245}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003246#endif /* MBEDTLS_SHA256_C */
Paul Bakker1ef83d62012-04-11 12:09:53 +00003247
Gilles Peskined2d59372021-05-12 22:43:27 +02003248#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384)
Rodrigo Dias Corread596ca82020-11-25 00:42:28 -03003249
Paul Bakkerca4ab492012-04-18 14:23:57 +00003250static void ssl_calc_finished_tls_sha384(
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003251 mbedtls_ssl_context *ssl, unsigned char *buf, int from)
Paul Bakkerca4ab492012-04-18 14:23:57 +00003252{
3253 int len = 12;
Paul Bakker3c2122f2013-06-24 19:03:14 +02003254 const char *sender;
Rodrigo Dias Corread596ca82020-11-25 00:42:28 -03003255 unsigned char padbuf[48];
Andrzej Kurekeb342242019-01-29 09:14:33 -05003256#if defined(MBEDTLS_USE_PSA_CRYPTO)
3257 size_t hash_size;
Jaeden Amero34973232019-02-20 10:32:28 +00003258 psa_hash_operation_t sha384_psa = PSA_HASH_OPERATION_INIT;
Andrzej Kurekeb342242019-01-29 09:14:33 -05003259 psa_status_t status;
3260#else
3261 mbedtls_sha512_context sha512;
3262#endif
Paul Bakkerca4ab492012-04-18 14:23:57 +00003263
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003264 mbedtls_ssl_session *session = ssl->session_negotiate;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003265 if (!session) {
Paul Bakker48916f92012-09-16 19:57:18 +00003266 session = ssl->session;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003267 }
Paul Bakker48916f92012-09-16 19:57:18 +00003268
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003269 sender = (from == MBEDTLS_SSL_IS_CLIENT)
Andrzej Kurekeb342242019-01-29 09:14:33 -05003270 ? "client finished"
3271 : "server finished";
3272
3273#if defined(MBEDTLS_USE_PSA_CRYPTO)
Andrzej Kurek972fba52019-01-30 03:29:12 -05003274 sha384_psa = psa_hash_operation_init();
Andrzej Kurekeb342242019-01-29 09:14:33 -05003275
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003276 MBEDTLS_SSL_DEBUG_MSG(2, ("=> calc PSA finished tls sha384"));
Andrzej Kurekeb342242019-01-29 09:14:33 -05003277
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003278 status = psa_hash_clone(&ssl->handshake->fin_sha384_psa, &sha384_psa);
3279 if (status != PSA_SUCCESS) {
3280 MBEDTLS_SSL_DEBUG_MSG(2, ("PSA hash clone failed"));
Andrzej Kurekeb342242019-01-29 09:14:33 -05003281 return;
3282 }
3283
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003284 status = psa_hash_finish(&sha384_psa, padbuf, sizeof(padbuf), &hash_size);
3285 if (status != PSA_SUCCESS) {
3286 MBEDTLS_SSL_DEBUG_MSG(2, ("PSA hash finish failed"));
Andrzej Kurekeb342242019-01-29 09:14:33 -05003287 return;
3288 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003289 MBEDTLS_SSL_DEBUG_BUF(3, "PSA calculated padbuf", padbuf, 48);
Andrzej Kurekeb342242019-01-29 09:14:33 -05003290#else
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003291 mbedtls_sha512_init(&sha512);
Manuel Pégourié-Gonnard001f2b62015-07-06 16:21:13 +02003292
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003293 MBEDTLS_SSL_DEBUG_MSG(2, ("=> calc finished tls sha384"));
Paul Bakkerca4ab492012-04-18 14:23:57 +00003294
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003295 mbedtls_sha512_clone(&sha512, &ssl->handshake->fin_sha512);
Paul Bakkerca4ab492012-04-18 14:23:57 +00003296
3297 /*
3298 * TLSv1.2:
3299 * hash = PRF( master, finished_label,
3300 * Hash( handshake ) )[0.11]
3301 */
3302
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003303#if !defined(MBEDTLS_SHA512_ALT)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003304 MBEDTLS_SSL_DEBUG_BUF(4, "finished sha512 state", (unsigned char *)
3305 sha512.state, sizeof(sha512.state));
Paul Bakker90995b52013-06-24 19:20:35 +02003306#endif
Gilles Peskinebb66dac2021-05-13 00:00:45 +02003307 /* mbedtls_sha512_finish_ret's output parameter is declared as a
Tom Cosgrove49f99bc2022-12-04 16:44:21 +00003308 * 64-byte buffer, but since we're using SHA-384, we know that the
Gilles Peskinebb66dac2021-05-13 00:00:45 +02003309 * output fits in 48 bytes. This is correct C, but GCC 11.1 warns
3310 * about it.
Rodrigo Dias Corread596ca82020-11-25 00:42:28 -03003311 */
Gilles Peskinebb66dac2021-05-13 00:00:45 +02003312#if defined(__GNUC__) && __GNUC__ >= 11
3313#pragma GCC diagnostic push
3314#pragma GCC diagnostic ignored "-Wstringop-overflow"
3315#endif
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003316 mbedtls_sha512_finish_ret(&sha512, padbuf);
Gilles Peskinebb66dac2021-05-13 00:00:45 +02003317#if defined(__GNUC__) && __GNUC__ >= 11
3318#pragma GCC diagnostic pop
3319#endif
Paul Bakkerca4ab492012-04-18 14:23:57 +00003320
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003321 mbedtls_sha512_free(&sha512);
Andrzej Kurekeb342242019-01-29 09:14:33 -05003322#endif
Paul Bakkerca4ab492012-04-18 14:23:57 +00003323
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003324 ssl->handshake->tls_prf(session->master, 48, sender,
3325 padbuf, 48, buf, len);
Paul Bakkerca4ab492012-04-18 14:23:57 +00003326
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003327 MBEDTLS_SSL_DEBUG_BUF(3, "calc finished result", buf, len);
Paul Bakkerca4ab492012-04-18 14:23:57 +00003328
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003329 mbedtls_platform_zeroize(padbuf, sizeof(padbuf));
Paul Bakkerca4ab492012-04-18 14:23:57 +00003330
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003331 MBEDTLS_SSL_DEBUG_MSG(2, ("<= calc finished"));
Paul Bakkerca4ab492012-04-18 14:23:57 +00003332}
Gilles Peskined2d59372021-05-12 22:43:27 +02003333#endif /* MBEDTLS_SHA512_C && !MBEDTLS_SHA512_NO_SHA384 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003334#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
Paul Bakkerca4ab492012-04-18 14:23:57 +00003335
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003336void mbedtls_ssl_handshake_wrapup_free_hs_transform(mbedtls_ssl_context *ssl)
Paul Bakker48916f92012-09-16 19:57:18 +00003337{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003338 MBEDTLS_SSL_DEBUG_MSG(3, ("=> handshake wrapup: final free"));
Paul Bakker48916f92012-09-16 19:57:18 +00003339
3340 /*
3341 * Free our handshake params
3342 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003343 mbedtls_ssl_handshake_free(ssl);
3344 mbedtls_free(ssl->handshake);
Paul Bakker48916f92012-09-16 19:57:18 +00003345 ssl->handshake = NULL;
3346
3347 /*
Shaun Case0e7791f2021-12-20 21:14:10 -08003348 * Free the previous transform and switch in the current one
Paul Bakker48916f92012-09-16 19:57:18 +00003349 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003350 if (ssl->transform) {
3351 mbedtls_ssl_transform_free(ssl->transform);
3352 mbedtls_free(ssl->transform);
Paul Bakker48916f92012-09-16 19:57:18 +00003353 }
3354 ssl->transform = ssl->transform_negotiate;
3355 ssl->transform_negotiate = NULL;
3356
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003357 MBEDTLS_SSL_DEBUG_MSG(3, ("<= handshake wrapup: final free"));
Manuel Pégourié-Gonnardabf16242014-09-23 09:42:16 +02003358}
3359
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003360void mbedtls_ssl_handshake_wrapup(mbedtls_ssl_context *ssl)
Manuel Pégourié-Gonnardabf16242014-09-23 09:42:16 +02003361{
3362 int resume = ssl->handshake->resume;
3363
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003364 MBEDTLS_SSL_DEBUG_MSG(3, ("=> handshake wrapup"));
Manuel Pégourié-Gonnardabf16242014-09-23 09:42:16 +02003365
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003366#if defined(MBEDTLS_SSL_RENEGOTIATION)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003367 if (ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS) {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003368 ssl->renego_status = MBEDTLS_SSL_RENEGOTIATION_DONE;
Manuel Pégourié-Gonnardabf16242014-09-23 09:42:16 +02003369 ssl->renego_records_seen = 0;
3370 }
Manuel Pégourié-Gonnard615e6772014-11-03 08:23:14 +01003371#endif
Manuel Pégourié-Gonnardabf16242014-09-23 09:42:16 +02003372
3373 /*
3374 * Free the previous session and switch in the current one
3375 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003376 if (ssl->session) {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003377#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
Manuel Pégourié-Gonnard1a034732014-11-04 17:36:18 +01003378 /* RFC 7366 3.1: keep the EtM state */
3379 ssl->session_negotiate->encrypt_then_mac =
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003380 ssl->session->encrypt_then_mac;
Manuel Pégourié-Gonnard1a034732014-11-04 17:36:18 +01003381#endif
3382
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003383 mbedtls_ssl_session_free(ssl->session);
3384 mbedtls_free(ssl->session);
Paul Bakker0a597072012-09-25 21:55:46 +00003385 }
3386 ssl->session = ssl->session_negotiate;
Paul Bakker48916f92012-09-16 19:57:18 +00003387 ssl->session_negotiate = NULL;
3388
Paul Bakker0a597072012-09-25 21:55:46 +00003389 /*
3390 * Add cache entry
3391 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003392 if (ssl->conf->f_set_cache != NULL &&
Manuel Pégourié-Gonnard12ad7982015-06-18 15:50:37 +02003393 ssl->session->id_len != 0 &&
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003394 resume == 0) {
3395 if (ssl->conf->f_set_cache(ssl->conf->p_cache, ssl->session) != 0) {
3396 MBEDTLS_SSL_DEBUG_MSG(1, ("cache did not store session"));
3397 }
Manuel Pégourié-Gonnardc086cce2013-08-02 14:13:02 +02003398 }
Paul Bakker0a597072012-09-25 21:55:46 +00003399
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003400#if defined(MBEDTLS_SSL_PROTO_DTLS)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003401 if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
3402 ssl->handshake->flight != NULL) {
Manuel Pégourié-Gonnard6b651412014-10-01 18:29:03 +02003403 /* Cancel handshake timer */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003404 mbedtls_ssl_set_timer(ssl, 0);
Manuel Pégourié-Gonnard6b651412014-10-01 18:29:03 +02003405
Manuel Pégourié-Gonnardabf16242014-09-23 09:42:16 +02003406 /* Keep last flight around in case we need to resend it:
3407 * we need the handshake and transform structures for that */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003408 MBEDTLS_SSL_DEBUG_MSG(3, ("skip freeing handshake and transform"));
3409 } else
Manuel Pégourié-Gonnardabf16242014-09-23 09:42:16 +02003410#endif
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003411 mbedtls_ssl_handshake_wrapup_free_hs_transform(ssl);
Manuel Pégourié-Gonnardabf16242014-09-23 09:42:16 +02003412
Paul Bakker48916f92012-09-16 19:57:18 +00003413 ssl->state++;
3414
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003415 MBEDTLS_SSL_DEBUG_MSG(3, ("<= handshake wrapup"));
Paul Bakker48916f92012-09-16 19:57:18 +00003416}
3417
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003418int mbedtls_ssl_write_finished(mbedtls_ssl_context *ssl)
Paul Bakker1ef83d62012-04-11 12:09:53 +00003419{
Manuel Pégourié-Gonnard879a4f92014-07-11 22:31:12 +02003420 int ret, hash_len;
Paul Bakker1ef83d62012-04-11 12:09:53 +00003421
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003422 MBEDTLS_SSL_DEBUG_MSG(2, ("=> write finished"));
Paul Bakker1ef83d62012-04-11 12:09:53 +00003423
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003424 mbedtls_ssl_update_out_pointers(ssl, ssl->transform_negotiate);
Paul Bakker92be97b2013-01-02 17:30:03 +01003425
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003426 ssl->handshake->calc_finished(ssl, ssl->out_msg + 4, ssl->conf->endpoint);
Paul Bakker1ef83d62012-04-11 12:09:53 +00003427
Manuel Pégourié-Gonnard214a8482016-02-22 11:27:26 +01003428 /*
3429 * RFC 5246 7.4.9 (Page 63) says 12 is the default length and ciphersuites
3430 * may define some other value. Currently (early 2016), no defined
3431 * ciphersuite does this (and this is unlikely to change as activity has
3432 * moved to TLS 1.3 now) so we can keep the hardcoded 12 here.
3433 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003434 hash_len = (ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0) ? 36 : 12;
Paul Bakker5121ce52009-01-03 21:22:43 +00003435
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003436#if defined(MBEDTLS_SSL_RENEGOTIATION)
Paul Bakker48916f92012-09-16 19:57:18 +00003437 ssl->verify_data_len = hash_len;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003438 memcpy(ssl->own_verify_data, ssl->out_msg + 4, hash_len);
Manuel Pégourié-Gonnard615e6772014-11-03 08:23:14 +01003439#endif
Paul Bakker48916f92012-09-16 19:57:18 +00003440
Paul Bakker5121ce52009-01-03 21:22:43 +00003441 ssl->out_msglen = 4 + hash_len;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003442 ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
3443 ssl->out_msg[0] = MBEDTLS_SSL_HS_FINISHED;
Paul Bakker5121ce52009-01-03 21:22:43 +00003444
3445 /*
3446 * In case of session resuming, invert the client and server
3447 * ChangeCipherSpec messages order.
3448 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003449 if (ssl->handshake->resume != 0) {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003450#if defined(MBEDTLS_SSL_CLI_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003451 if (ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT) {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003452 ssl->state = MBEDTLS_SSL_HANDSHAKE_WRAPUP;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003453 }
Manuel Pégourié-Gonnardd16d1cb2014-11-20 18:15:05 +01003454#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003455#if defined(MBEDTLS_SSL_SRV_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003456 if (ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER) {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003457 ssl->state = MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003458 }
Manuel Pégourié-Gonnardd16d1cb2014-11-20 18:15:05 +01003459#endif
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003460 } else {
Paul Bakker5121ce52009-01-03 21:22:43 +00003461 ssl->state++;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003462 }
Paul Bakker5121ce52009-01-03 21:22:43 +00003463
Paul Bakker48916f92012-09-16 19:57:18 +00003464 /*
Paul Bakkerb9e4e2c2014-05-01 14:18:25 +02003465 * Switch to our negotiated transform and session parameters for outbound
3466 * data.
Paul Bakker48916f92012-09-16 19:57:18 +00003467 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003468 MBEDTLS_SSL_DEBUG_MSG(3, ("switching to new transform spec for outbound data"));
Manuel Pégourié-Gonnard5afb1672014-02-16 18:33:22 +01003469
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003470#if defined(MBEDTLS_SSL_PROTO_DTLS)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003471 if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
Manuel Pégourié-Gonnard879a4f92014-07-11 22:31:12 +02003472 unsigned char i;
3473
Manuel Pégourié-Gonnard5d8ba532014-09-19 15:09:21 +02003474 /* Remember current epoch settings for resending */
3475 ssl->handshake->alt_transform_out = ssl->transform_out;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003476 memcpy(ssl->handshake->alt_out_ctr, ssl->cur_out_ctr, 8);
Manuel Pégourié-Gonnard5d8ba532014-09-19 15:09:21 +02003477
Manuel Pégourié-Gonnard879a4f92014-07-11 22:31:12 +02003478 /* Set sequence_number to zero */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003479 memset(ssl->cur_out_ctr + 2, 0, 6);
Manuel Pégourié-Gonnard879a4f92014-07-11 22:31:12 +02003480
3481 /* Increment epoch */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003482 for (i = 2; i > 0; i--) {
3483 if (++ssl->cur_out_ctr[i - 1] != 0) {
Manuel Pégourié-Gonnard879a4f92014-07-11 22:31:12 +02003484 break;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003485 }
3486 }
Manuel Pégourié-Gonnard879a4f92014-07-11 22:31:12 +02003487
3488 /* The loop goes to its end iff the counter is wrapping */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003489 if (i == 0) {
3490 MBEDTLS_SSL_DEBUG_MSG(1, ("DTLS epoch would wrap"));
3491 return MBEDTLS_ERR_SSL_COUNTER_WRAPPING;
Manuel Pégourié-Gonnard879a4f92014-07-11 22:31:12 +02003492 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003493 } else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003494#endif /* MBEDTLS_SSL_PROTO_DTLS */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003495 memset(ssl->cur_out_ctr, 0, 8);
Paul Bakker5121ce52009-01-03 21:22:43 +00003496
Manuel Pégourié-Gonnard5d8ba532014-09-19 15:09:21 +02003497 ssl->transform_out = ssl->transform_negotiate;
3498 ssl->session_out = ssl->session_negotiate;
3499
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003500#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003501 if (mbedtls_ssl_hw_record_activate != NULL) {
3502 if ((ret = mbedtls_ssl_hw_record_activate(ssl, MBEDTLS_SSL_CHANNEL_OUTBOUND)) != 0) {
3503 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_hw_record_activate", ret);
3504 return MBEDTLS_ERR_SSL_HW_ACCEL_FAILED;
Paul Bakker07eb38b2012-12-19 14:42:06 +01003505 }
3506 }
3507#endif
3508
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003509#if defined(MBEDTLS_SSL_PROTO_DTLS)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003510 if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
3511 mbedtls_ssl_send_flight_completed(ssl);
3512 }
Manuel Pégourié-Gonnard7de3c9e2014-09-29 15:29:48 +02003513#endif
3514
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003515 if ((ret = mbedtls_ssl_write_handshake_msg(ssl)) != 0) {
3516 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_handshake_msg", ret);
3517 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00003518 }
3519
Manuel Pégourié-Gonnard87a346f2017-09-13 12:45:21 +02003520#if defined(MBEDTLS_SSL_PROTO_DTLS)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003521 if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
3522 (ret = mbedtls_ssl_flight_transmit(ssl)) != 0) {
3523 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_flight_transmit", ret);
3524 return ret;
Manuel Pégourié-Gonnard87a346f2017-09-13 12:45:21 +02003525 }
3526#endif
3527
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003528 MBEDTLS_SSL_DEBUG_MSG(2, ("<= write finished"));
Paul Bakker5121ce52009-01-03 21:22:43 +00003529
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003530 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +00003531}
3532
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003533#if defined(MBEDTLS_SSL_PROTO_SSL3)
Manuel Pégourié-Gonnardca6440b2014-09-10 12:39:54 +00003534#define SSL_MAX_HASH_LEN 36
3535#else
3536#define SSL_MAX_HASH_LEN 12
3537#endif
3538
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003539int mbedtls_ssl_parse_finished(mbedtls_ssl_context *ssl)
Paul Bakker5121ce52009-01-03 21:22:43 +00003540{
Janos Follath865b3eb2019-12-16 11:46:15 +00003541 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard879a4f92014-07-11 22:31:12 +02003542 unsigned int hash_len;
Manuel Pégourié-Gonnardca6440b2014-09-10 12:39:54 +00003543 unsigned char buf[SSL_MAX_HASH_LEN];
Paul Bakker5121ce52009-01-03 21:22:43 +00003544
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003545 MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse finished"));
Paul Bakker5121ce52009-01-03 21:22:43 +00003546
Gilles Peskine622d8042021-12-13 14:38:40 +01003547 /* There is currently no ciphersuite using another length with TLS 1.2 */
3548#if defined(MBEDTLS_SSL_PROTO_SSL3)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003549 if (ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0) {
Gilles Peskine622d8042021-12-13 14:38:40 +01003550 hash_len = 36;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003551 } else
Gilles Peskine622d8042021-12-13 14:38:40 +01003552#endif
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003553 hash_len = 12;
Gilles Peskine622d8042021-12-13 14:38:40 +01003554
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003555 ssl->handshake->calc_finished(ssl, buf, ssl->conf->endpoint ^ 1);
Paul Bakker5121ce52009-01-03 21:22:43 +00003556
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003557 if ((ret = mbedtls_ssl_read_record(ssl, 1)) != 0) {
3558 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_read_record", ret);
Gilles Peskinef91b2e52021-12-13 12:36:15 +01003559 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00003560 }
3561
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003562 if (ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE) {
3563 MBEDTLS_SSL_DEBUG_MSG(1, ("bad finished message"));
3564 mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
3565 MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE);
Gilles Peskinef91b2e52021-12-13 12:36:15 +01003566 ret = MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
3567 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00003568 }
3569
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003570 if (ssl->in_msg[0] != MBEDTLS_SSL_HS_FINISHED ||
3571 ssl->in_hslen != mbedtls_ssl_hs_hdr_len(ssl) + hash_len) {
3572 MBEDTLS_SSL_DEBUG_MSG(1, ("bad finished message"));
3573 mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
3574 MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
Gilles Peskinef91b2e52021-12-13 12:36:15 +01003575 ret = MBEDTLS_ERR_SSL_BAD_HS_FINISHED;
3576 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00003577 }
3578
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003579 if (mbedtls_ct_memcmp(ssl->in_msg + mbedtls_ssl_hs_hdr_len(ssl),
3580 buf, hash_len) != 0) {
3581 MBEDTLS_SSL_DEBUG_MSG(1, ("bad finished message"));
3582 mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
3583 MBEDTLS_SSL_ALERT_MSG_DECRYPT_ERROR);
Gilles Peskinef91b2e52021-12-13 12:36:15 +01003584 ret = MBEDTLS_ERR_SSL_BAD_HS_FINISHED;
3585 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00003586 }
3587
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003588#if defined(MBEDTLS_SSL_RENEGOTIATION)
Paul Bakker48916f92012-09-16 19:57:18 +00003589 ssl->verify_data_len = hash_len;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003590 memcpy(ssl->peer_verify_data, buf, hash_len);
Manuel Pégourié-Gonnard615e6772014-11-03 08:23:14 +01003591#endif
Paul Bakker48916f92012-09-16 19:57:18 +00003592
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003593 if (ssl->handshake->resume != 0) {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003594#if defined(MBEDTLS_SSL_CLI_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003595 if (ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT) {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003596 ssl->state = MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003597 }
Manuel Pégourié-Gonnardd16d1cb2014-11-20 18:15:05 +01003598#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003599#if defined(MBEDTLS_SSL_SRV_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003600 if (ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER) {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003601 ssl->state = MBEDTLS_SSL_HANDSHAKE_WRAPUP;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003602 }
Manuel Pégourié-Gonnardd16d1cb2014-11-20 18:15:05 +01003603#endif
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003604 } else {
Paul Bakker5121ce52009-01-03 21:22:43 +00003605 ssl->state++;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003606 }
Paul Bakker5121ce52009-01-03 21:22:43 +00003607
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003608#if defined(MBEDTLS_SSL_PROTO_DTLS)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003609 if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
3610 mbedtls_ssl_recv_flight_completed(ssl);
3611 }
Manuel Pégourié-Gonnard5d8ba532014-09-19 15:09:21 +02003612#endif
3613
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003614 MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse finished"));
Paul Bakker5121ce52009-01-03 21:22:43 +00003615
Gilles Peskinef91b2e52021-12-13 12:36:15 +01003616exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003617 mbedtls_platform_zeroize(buf, hash_len);
3618 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00003619}
3620
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003621static void ssl_handshake_params_init(mbedtls_ssl_handshake_params *handshake)
Paul Bakkeraccaffe2014-06-26 13:37:14 +02003622{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003623 memset(handshake, 0, sizeof(mbedtls_ssl_handshake_params));
Paul Bakkeraccaffe2014-06-26 13:37:14 +02003624
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003625#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
3626 defined(MBEDTLS_SSL_PROTO_TLS1_1)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003627 mbedtls_md5_init(&handshake->fin_md5);
3628 mbedtls_sha1_init(&handshake->fin_sha1);
3629 mbedtls_md5_starts_ret(&handshake->fin_md5);
3630 mbedtls_sha1_starts_ret(&handshake->fin_sha1);
Paul Bakkeraccaffe2014-06-26 13:37:14 +02003631#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003632#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
3633#if defined(MBEDTLS_SHA256_C)
Andrzej Kurekeb342242019-01-29 09:14:33 -05003634#if defined(MBEDTLS_USE_PSA_CRYPTO)
3635 handshake->fin_sha256_psa = psa_hash_operation_init();
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003636 psa_hash_setup(&handshake->fin_sha256_psa, PSA_ALG_SHA_256);
Andrzej Kurekeb342242019-01-29 09:14:33 -05003637#else
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003638 mbedtls_sha256_init(&handshake->fin_sha256);
3639 mbedtls_sha256_starts_ret(&handshake->fin_sha256, 0);
Paul Bakkeraccaffe2014-06-26 13:37:14 +02003640#endif
Andrzej Kurekeb342242019-01-29 09:14:33 -05003641#endif
Gilles Peskined2d59372021-05-12 22:43:27 +02003642#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384)
Andrzej Kurekeb342242019-01-29 09:14:33 -05003643#if defined(MBEDTLS_USE_PSA_CRYPTO)
Andrzej Kurek972fba52019-01-30 03:29:12 -05003644 handshake->fin_sha384_psa = psa_hash_operation_init();
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003645 psa_hash_setup(&handshake->fin_sha384_psa, PSA_ALG_SHA_384);
Andrzej Kurekeb342242019-01-29 09:14:33 -05003646#else
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003647 mbedtls_sha512_init(&handshake->fin_sha512);
3648 mbedtls_sha512_starts_ret(&handshake->fin_sha512, 1);
Paul Bakkeraccaffe2014-06-26 13:37:14 +02003649#endif
Andrzej Kurekeb342242019-01-29 09:14:33 -05003650#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003651#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
Paul Bakkeraccaffe2014-06-26 13:37:14 +02003652
3653 handshake->update_checksum = ssl_update_checksum_start;
Hanno Becker7e5437a2017-04-28 17:15:26 +01003654
3655#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
Gilles Peskineeccd8882020-03-10 12:19:08 +01003656 defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003657 mbedtls_ssl_sig_hash_set_init(&handshake->hash_algs);
Hanno Becker7e5437a2017-04-28 17:15:26 +01003658#endif
Paul Bakkeraccaffe2014-06-26 13:37:14 +02003659
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003660#if defined(MBEDTLS_DHM_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003661 mbedtls_dhm_init(&handshake->dhm_ctx);
Paul Bakkeraccaffe2014-06-26 13:37:14 +02003662#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003663#if defined(MBEDTLS_ECDH_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003664 mbedtls_ecdh_init(&handshake->ecdh_ctx);
Paul Bakkeraccaffe2014-06-26 13:37:14 +02003665#endif
Manuel Pégourié-Gonnardeef142d2015-09-16 10:05:04 +02003666#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003667 mbedtls_ecjpake_init(&handshake->ecjpake_ctx);
Manuel Pégourié-Gonnard77c06462015-09-17 13:59:49 +02003668#if defined(MBEDTLS_SSL_CLI_C)
3669 handshake->ecjpake_cache = NULL;
3670 handshake->ecjpake_cache_len = 0;
3671#endif
Manuel Pégourié-Gonnard76cfd3f2015-09-15 12:10:54 +02003672#endif
Manuel Pégourié-Gonnardcdc26ae2015-06-19 12:16:31 +02003673
Gilles Peskineeccd8882020-03-10 12:19:08 +01003674#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003675 mbedtls_x509_crt_restart_init(&handshake->ecrs_ctx);
Manuel Pégourié-Gonnard862cde52017-05-17 11:56:15 +02003676#endif
3677
Manuel Pégourié-Gonnardcdc26ae2015-06-19 12:16:31 +02003678#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
3679 handshake->sni_authmode = MBEDTLS_SSL_VERIFY_UNSET;
3680#endif
Hanno Becker75173122019-02-06 16:18:31 +00003681
3682#if defined(MBEDTLS_X509_CRT_PARSE_C) && \
3683 !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003684 mbedtls_pk_init(&handshake->peer_pubkey);
Hanno Becker75173122019-02-06 16:18:31 +00003685#endif
Paul Bakkeraccaffe2014-06-26 13:37:14 +02003686}
3687
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003688void mbedtls_ssl_transform_init(mbedtls_ssl_transform *transform)
Paul Bakkeraccaffe2014-06-26 13:37:14 +02003689{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003690 memset(transform, 0, sizeof(mbedtls_ssl_transform));
Paul Bakker84bbeb52014-07-01 14:53:22 +02003691
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003692 mbedtls_cipher_init(&transform->cipher_ctx_enc);
3693 mbedtls_cipher_init(&transform->cipher_ctx_dec);
Paul Bakker84bbeb52014-07-01 14:53:22 +02003694
Hanno Beckerd56ed242018-01-03 15:32:51 +00003695#if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003696 mbedtls_md_init(&transform->md_ctx_enc);
3697 mbedtls_md_init(&transform->md_ctx_dec);
Hanno Beckerd56ed242018-01-03 15:32:51 +00003698#endif
Paul Bakkeraccaffe2014-06-26 13:37:14 +02003699}
3700
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003701void mbedtls_ssl_session_init(mbedtls_ssl_session *session)
Paul Bakkeraccaffe2014-06-26 13:37:14 +02003702{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003703 memset(session, 0, sizeof(mbedtls_ssl_session));
Paul Bakkeraccaffe2014-06-26 13:37:14 +02003704}
3705
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +02003706MBEDTLS_CHECK_RETURN_CRITICAL
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003707static int ssl_handshake_init(mbedtls_ssl_context *ssl)
Paul Bakker48916f92012-09-16 19:57:18 +00003708{
Paul Bakkeraccaffe2014-06-26 13:37:14 +02003709 /* Clear old handshake information if present */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003710 if (ssl->transform_negotiate) {
3711 mbedtls_ssl_transform_free(ssl->transform_negotiate);
3712 }
3713 if (ssl->session_negotiate) {
3714 mbedtls_ssl_session_free(ssl->session_negotiate);
3715 }
3716 if (ssl->handshake) {
3717 mbedtls_ssl_handshake_free(ssl);
3718 }
Paul Bakkeraccaffe2014-06-26 13:37:14 +02003719
3720 /*
3721 * Either the pointers are now NULL or cleared properly and can be freed.
3722 * Now allocate missing structures.
3723 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003724 if (ssl->transform_negotiate == NULL) {
3725 ssl->transform_negotiate = mbedtls_calloc(1, sizeof(mbedtls_ssl_transform));
Paul Bakkerb9cfaa02013-10-11 18:58:55 +02003726 }
Paul Bakker48916f92012-09-16 19:57:18 +00003727
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003728 if (ssl->session_negotiate == NULL) {
3729 ssl->session_negotiate = mbedtls_calloc(1, sizeof(mbedtls_ssl_session));
Paul Bakkerb9cfaa02013-10-11 18:58:55 +02003730 }
Paul Bakker48916f92012-09-16 19:57:18 +00003731
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003732 if (ssl->handshake == NULL) {
3733 ssl->handshake = mbedtls_calloc(1, sizeof(mbedtls_ssl_handshake_params));
Paul Bakkerb9cfaa02013-10-11 18:58:55 +02003734 }
Andrzej Kurek0afa2a12020-03-03 10:39:58 -05003735#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
3736 /* If the buffers are too small - reallocate */
Andrzej Kurek8ea68722020-04-03 06:40:47 -04003737
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003738 handle_buffer_resizing(ssl, 0, MBEDTLS_SSL_IN_BUFFER_LEN,
3739 MBEDTLS_SSL_OUT_BUFFER_LEN);
Andrzej Kurek0afa2a12020-03-03 10:39:58 -05003740#endif
Paul Bakker48916f92012-09-16 19:57:18 +00003741
Paul Bakkeraccaffe2014-06-26 13:37:14 +02003742 /* All pointers should exist and can be directly freed without issue */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003743 if (ssl->handshake == NULL ||
Paul Bakker48916f92012-09-16 19:57:18 +00003744 ssl->transform_negotiate == NULL ||
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003745 ssl->session_negotiate == NULL) {
3746 MBEDTLS_SSL_DEBUG_MSG(1, ("alloc() of ssl sub-contexts failed"));
Paul Bakkeraccaffe2014-06-26 13:37:14 +02003747
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003748 mbedtls_free(ssl->handshake);
3749 mbedtls_free(ssl->transform_negotiate);
3750 mbedtls_free(ssl->session_negotiate);
Paul Bakkeraccaffe2014-06-26 13:37:14 +02003751
3752 ssl->handshake = NULL;
3753 ssl->transform_negotiate = NULL;
3754 ssl->session_negotiate = NULL;
3755
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003756 return MBEDTLS_ERR_SSL_ALLOC_FAILED;
Paul Bakker48916f92012-09-16 19:57:18 +00003757 }
3758
Paul Bakkeraccaffe2014-06-26 13:37:14 +02003759 /* Initialize structures */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003760 mbedtls_ssl_session_init(ssl->session_negotiate);
3761 mbedtls_ssl_transform_init(ssl->transform_negotiate);
3762 ssl_handshake_params_init(ssl->handshake);
Paul Bakker968afaa2014-07-09 11:09:24 +02003763
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003764#if defined(MBEDTLS_SSL_PROTO_DTLS)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003765 if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
Manuel Pégourié-Gonnard06939ce2015-05-11 11:25:46 +02003766 ssl->handshake->alt_transform_out = ssl->transform_out;
Manuel Pégourié-Gonnard5d8ba532014-09-19 15:09:21 +02003767
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003768 if (ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT) {
Manuel Pégourié-Gonnard06939ce2015-05-11 11:25:46 +02003769 ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_PREPARING;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003770 } else {
Manuel Pégourié-Gonnard06939ce2015-05-11 11:25:46 +02003771 ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_WAITING;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003772 }
Manuel Pégourié-Gonnard286a1362015-05-13 16:22:05 +02003773
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003774 mbedtls_ssl_set_timer(ssl, 0);
Manuel Pégourié-Gonnard06939ce2015-05-11 11:25:46 +02003775 }
Manuel Pégourié-Gonnard5d8ba532014-09-19 15:09:21 +02003776#endif
3777
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003778 return 0;
Paul Bakker48916f92012-09-16 19:57:18 +00003779}
3780
Manuel Pégourié-Gonnarde057d3b2015-05-20 10:59:43 +02003781#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C)
Manuel Pégourié-Gonnard7d38d212014-07-23 17:52:09 +02003782/* Dummy cookie callbacks for defaults */
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +02003783MBEDTLS_CHECK_RETURN_CRITICAL
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003784static int ssl_cookie_write_dummy(void *ctx,
3785 unsigned char **p, unsigned char *end,
3786 const unsigned char *cli_id, size_t cli_id_len)
Manuel Pégourié-Gonnard7d38d212014-07-23 17:52:09 +02003787{
3788 ((void) ctx);
3789 ((void) p);
3790 ((void) end);
3791 ((void) cli_id);
3792 ((void) cli_id_len);
3793
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003794 return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
Manuel Pégourié-Gonnard7d38d212014-07-23 17:52:09 +02003795}
3796
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +02003797MBEDTLS_CHECK_RETURN_CRITICAL
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003798static int ssl_cookie_check_dummy(void *ctx,
3799 const unsigned char *cookie, size_t cookie_len,
3800 const unsigned char *cli_id, size_t cli_id_len)
Manuel Pégourié-Gonnard7d38d212014-07-23 17:52:09 +02003801{
3802 ((void) ctx);
3803 ((void) cookie);
3804 ((void) cookie_len);
3805 ((void) cli_id);
3806 ((void) cli_id_len);
3807
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003808 return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
Manuel Pégourié-Gonnard7d38d212014-07-23 17:52:09 +02003809}
Manuel Pégourié-Gonnarde057d3b2015-05-20 10:59:43 +02003810#endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY && MBEDTLS_SSL_SRV_C */
Manuel Pégourié-Gonnard7d38d212014-07-23 17:52:09 +02003811
Paul Bakker5121ce52009-01-03 21:22:43 +00003812/*
3813 * Initialize an SSL context
3814 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003815void mbedtls_ssl_init(mbedtls_ssl_context *ssl)
Manuel Pégourié-Gonnard41d479e2015-04-29 00:48:22 +02003816{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003817 memset(ssl, 0, sizeof(mbedtls_ssl_context));
Manuel Pégourié-Gonnard41d479e2015-04-29 00:48:22 +02003818}
3819
3820/*
3821 * Setup an SSL context
3822 */
Hanno Becker2a43f6f2018-08-10 11:12:52 +01003823
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003824int mbedtls_ssl_setup(mbedtls_ssl_context *ssl,
3825 const mbedtls_ssl_config *conf)
Paul Bakker5121ce52009-01-03 21:22:43 +00003826{
Janos Follath865b3eb2019-12-16 11:46:15 +00003827 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Darryl Greenb33cc762019-11-28 14:29:44 +00003828 size_t in_buf_len = MBEDTLS_SSL_IN_BUFFER_LEN;
3829 size_t out_buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN;
Paul Bakker5121ce52009-01-03 21:22:43 +00003830
Manuel Pégourié-Gonnarddef0bbe2015-05-04 14:56:36 +02003831 ssl->conf = conf;
Paul Bakker62f2dee2012-09-28 07:31:51 +00003832
3833 /*
Manuel Pégourié-Gonnard06193482014-02-14 08:39:32 +01003834 * Prepare base structures
Paul Bakker62f2dee2012-09-28 07:31:51 +00003835 */
k-stachowiakc9a5f022018-07-24 13:53:31 +02003836
3837 /* Set to NULL in case of an error condition */
3838 ssl->out_buf = NULL;
k-stachowiaka47911c2018-07-04 17:41:58 +02003839
Darryl Greenb33cc762019-11-28 14:29:44 +00003840#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
3841 ssl->in_buf_len = in_buf_len;
3842#endif
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003843 ssl->in_buf = mbedtls_calloc(1, in_buf_len);
3844 if (ssl->in_buf == NULL) {
3845 MBEDTLS_SSL_DEBUG_MSG(1, ("alloc(%" MBEDTLS_PRINTF_SIZET " bytes) failed", in_buf_len));
k-stachowiak9f7798e2018-07-31 16:52:32 +02003846 ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
k-stachowiaka47911c2018-07-04 17:41:58 +02003847 goto error;
Angus Grattond8213d02016-05-25 20:56:48 +10003848 }
3849
Darryl Greenb33cc762019-11-28 14:29:44 +00003850#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
3851 ssl->out_buf_len = out_buf_len;
3852#endif
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003853 ssl->out_buf = mbedtls_calloc(1, out_buf_len);
3854 if (ssl->out_buf == NULL) {
3855 MBEDTLS_SSL_DEBUG_MSG(1, ("alloc(%" MBEDTLS_PRINTF_SIZET " bytes) failed", out_buf_len));
k-stachowiak9f7798e2018-07-31 16:52:32 +02003856 ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
k-stachowiaka47911c2018-07-04 17:41:58 +02003857 goto error;
Paul Bakker5121ce52009-01-03 21:22:43 +00003858 }
3859
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003860 mbedtls_ssl_reset_in_out_pointers(ssl);
Manuel Pégourié-Gonnard419d5ae2015-05-04 19:32:36 +02003861
Johan Pascalb62bb512015-12-03 21:56:45 +01003862#if defined(MBEDTLS_SSL_DTLS_SRTP)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003863 memset(&ssl->dtls_srtp_info, 0, sizeof(ssl->dtls_srtp_info));
Johan Pascalb62bb512015-12-03 21:56:45 +01003864#endif
3865
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003866 if ((ret = ssl_handshake_init(ssl)) != 0) {
k-stachowiaka47911c2018-07-04 17:41:58 +02003867 goto error;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003868 }
Paul Bakker5121ce52009-01-03 21:22:43 +00003869
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003870 return 0;
k-stachowiaka47911c2018-07-04 17:41:58 +02003871
3872error:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003873 mbedtls_free(ssl->in_buf);
3874 mbedtls_free(ssl->out_buf);
k-stachowiaka47911c2018-07-04 17:41:58 +02003875
3876 ssl->conf = NULL;
3877
Darryl Greenb33cc762019-11-28 14:29:44 +00003878#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
3879 ssl->in_buf_len = 0;
3880 ssl->out_buf_len = 0;
3881#endif
k-stachowiaka47911c2018-07-04 17:41:58 +02003882 ssl->in_buf = NULL;
3883 ssl->out_buf = NULL;
3884
3885 ssl->in_hdr = NULL;
3886 ssl->in_ctr = NULL;
3887 ssl->in_len = NULL;
3888 ssl->in_iv = NULL;
3889 ssl->in_msg = NULL;
3890
3891 ssl->out_hdr = NULL;
3892 ssl->out_ctr = NULL;
3893 ssl->out_len = NULL;
3894 ssl->out_iv = NULL;
3895 ssl->out_msg = NULL;
3896
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003897 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00003898}
3899
3900/*
Paul Bakker7eb013f2011-10-06 12:37:39 +00003901 * Reset an initialized and used SSL context for re-use while retaining
3902 * all application-set variables, function pointers and data.
Manuel Pégourié-Gonnard3f09b6d2015-09-08 11:58:14 +02003903 *
3904 * If partial is non-zero, keep data in the input buffer and client ID.
3905 * (Use when a DTLS client reconnects from the same port.)
Paul Bakker7eb013f2011-10-06 12:37:39 +00003906 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003907int mbedtls_ssl_session_reset_int(mbedtls_ssl_context *ssl, int partial)
Paul Bakker7eb013f2011-10-06 12:37:39 +00003908{
Janos Follath865b3eb2019-12-16 11:46:15 +00003909 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Darryl Greenb33cc762019-11-28 14:29:44 +00003910#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
3911 size_t in_buf_len = ssl->in_buf_len;
3912 size_t out_buf_len = ssl->out_buf_len;
3913#else
3914 size_t in_buf_len = MBEDTLS_SSL_IN_BUFFER_LEN;
3915 size_t out_buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN;
3916#endif
Paul Bakker48916f92012-09-16 19:57:18 +00003917
Hanno Becker7e772132018-08-10 12:38:21 +01003918#if !defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) || \
3919 !defined(MBEDTLS_SSL_SRV_C)
3920 ((void) partial);
3921#endif
3922
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003923 ssl->state = MBEDTLS_SSL_HELLO_REQUEST;
Manuel Pégourié-Gonnard615e6772014-11-03 08:23:14 +01003924
Manuel Pégourié-Gonnard286a1362015-05-13 16:22:05 +02003925 /* Cancel any possibly running timer */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003926 mbedtls_ssl_set_timer(ssl, 0);
Manuel Pégourié-Gonnard286a1362015-05-13 16:22:05 +02003927
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003928#if defined(MBEDTLS_SSL_RENEGOTIATION)
3929 ssl->renego_status = MBEDTLS_SSL_INITIAL_HANDSHAKE;
Manuel Pégourié-Gonnard615e6772014-11-03 08:23:14 +01003930 ssl->renego_records_seen = 0;
Paul Bakker48916f92012-09-16 19:57:18 +00003931
3932 ssl->verify_data_len = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003933 memset(ssl->own_verify_data, 0, MBEDTLS_SSL_VERIFY_DATA_MAX_LEN);
3934 memset(ssl->peer_verify_data, 0, MBEDTLS_SSL_VERIFY_DATA_MAX_LEN);
Manuel Pégourié-Gonnard615e6772014-11-03 08:23:14 +01003935#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003936 ssl->secure_renegotiation = MBEDTLS_SSL_LEGACY_RENEGOTIATION;
Paul Bakker48916f92012-09-16 19:57:18 +00003937
Paul Bakker7eb013f2011-10-06 12:37:39 +00003938 ssl->in_offt = NULL;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003939 mbedtls_ssl_reset_in_out_pointers(ssl);
Paul Bakker7eb013f2011-10-06 12:37:39 +00003940
3941 ssl->in_msgtype = 0;
3942 ssl->in_msglen = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003943#if defined(MBEDTLS_SSL_PROTO_DTLS)
Manuel Pégourié-Gonnardb2f3be82014-07-10 17:54:52 +02003944 ssl->next_record_offset = 0;
Manuel Pégourié-Gonnard246c13a2014-09-24 13:56:09 +02003945 ssl->in_epoch = 0;
Manuel Pégourié-Gonnardb2f3be82014-07-10 17:54:52 +02003946#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003947#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003948 mbedtls_ssl_dtls_replay_reset(ssl);
Manuel Pégourié-Gonnardb47368a2014-09-24 13:29:58 +02003949#endif
Paul Bakker7eb013f2011-10-06 12:37:39 +00003950
3951 ssl->in_hslen = 0;
3952 ssl->nb_zero = 0;
Hanno Beckeraf0665d2017-05-24 09:16:26 +01003953
3954 ssl->keep_current_message = 0;
Paul Bakker7eb013f2011-10-06 12:37:39 +00003955
3956 ssl->out_msgtype = 0;
3957 ssl->out_msglen = 0;
3958 ssl->out_left = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003959#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003960 if (ssl->split_done != MBEDTLS_SSL_CBC_RECORD_SPLITTING_DISABLED) {
Manuel Pégourié-Gonnardcfa477e2015-01-07 14:50:54 +01003961 ssl->split_done = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003962 }
Manuel Pégourié-Gonnardd76314c2015-01-07 12:39:44 +01003963#endif
Paul Bakker7eb013f2011-10-06 12:37:39 +00003964
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003965 memset(ssl->cur_out_ctr, 0, sizeof(ssl->cur_out_ctr));
Hanno Becker19859472018-08-06 09:40:20 +01003966
Paul Bakker48916f92012-09-16 19:57:18 +00003967 ssl->transform_in = NULL;
3968 ssl->transform_out = NULL;
Paul Bakker7eb013f2011-10-06 12:37:39 +00003969
Hanno Becker78640902018-08-13 16:35:15 +01003970 ssl->session_in = NULL;
3971 ssl->session_out = NULL;
3972
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003973 memset(ssl->out_buf, 0, out_buf_len);
Hanno Becker4ccbf062018-08-10 11:20:38 +01003974
David Horstmannd4f22082022-10-26 18:25:14 +01003975 int clear_in_buf = 1;
Hanno Becker4ccbf062018-08-10 11:20:38 +01003976#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003977 if (partial != 0) {
David Horstmannd4f22082022-10-26 18:25:14 +01003978 clear_in_buf = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003979 }
Hanno Becker4ccbf062018-08-10 11:20:38 +01003980#endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE && MBEDTLS_SSL_SRV_C */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003981 if (clear_in_buf) {
Hanno Becker4ccbf062018-08-10 11:20:38 +01003982 ssl->in_left = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003983 memset(ssl->in_buf, 0, in_buf_len);
Hanno Becker4ccbf062018-08-10 11:20:38 +01003984 }
Paul Bakker05ef8352012-05-08 09:17:57 +00003985
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003986#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003987 if (mbedtls_ssl_hw_record_reset != NULL) {
3988 MBEDTLS_SSL_DEBUG_MSG(2, ("going for mbedtls_ssl_hw_record_reset()"));
3989 if ((ret = mbedtls_ssl_hw_record_reset(ssl)) != 0) {
3990 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_hw_record_reset", ret);
3991 return MBEDTLS_ERR_SSL_HW_ACCEL_FAILED;
Paul Bakker2770fbd2012-07-03 13:30:23 +00003992 }
Paul Bakker05ef8352012-05-08 09:17:57 +00003993 }
3994#endif
Paul Bakker2770fbd2012-07-03 13:30:23 +00003995
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01003996 if (ssl->transform) {
3997 mbedtls_ssl_transform_free(ssl->transform);
3998 mbedtls_free(ssl->transform);
Paul Bakker48916f92012-09-16 19:57:18 +00003999 ssl->transform = NULL;
Paul Bakker2770fbd2012-07-03 13:30:23 +00004000 }
Paul Bakker48916f92012-09-16 19:57:18 +00004001
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004002 if (ssl->session) {
4003 mbedtls_ssl_session_free(ssl->session);
4004 mbedtls_free(ssl->session);
Paul Bakkerc0463502013-02-14 11:19:38 +01004005 ssl->session = NULL;
4006 }
4007
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004008#if defined(MBEDTLS_SSL_ALPN)
Manuel Pégourié-Gonnard7e250d42014-04-04 16:08:41 +02004009 ssl->alpn_chosen = NULL;
4010#endif
4011
Manuel Pégourié-Gonnarde057d3b2015-05-20 10:59:43 +02004012#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C)
David Horstmannb5b1ed22022-10-27 13:21:49 +01004013 int free_cli_id = 1;
Hanno Becker4ccbf062018-08-10 11:20:38 +01004014#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004015 if (partial != 0) {
David Horstmannd4f22082022-10-26 18:25:14 +01004016 free_cli_id = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004017 }
Hanno Becker4ccbf062018-08-10 11:20:38 +01004018#endif
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004019 if (free_cli_id) {
4020 mbedtls_free(ssl->cli_id);
Manuel Pégourié-Gonnard3f09b6d2015-09-08 11:58:14 +02004021 ssl->cli_id = NULL;
4022 ssl->cli_id_len = 0;
4023 }
Manuel Pégourié-Gonnard43c02182014-07-22 17:32:01 +02004024#endif
4025
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004026 if ((ret = ssl_handshake_init(ssl)) != 0) {
4027 return ret;
4028 }
Paul Bakker2770fbd2012-07-03 13:30:23 +00004029
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004030 return 0;
Paul Bakker7eb013f2011-10-06 12:37:39 +00004031}
4032
Manuel Pégourié-Gonnard779e4292013-08-03 13:50:48 +02004033/*
Manuel Pégourié-Gonnard3f09b6d2015-09-08 11:58:14 +02004034 * Reset an initialized and used SSL context for re-use while retaining
4035 * all application-set variables, function pointers and data.
4036 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004037int mbedtls_ssl_session_reset(mbedtls_ssl_context *ssl)
Manuel Pégourié-Gonnard3f09b6d2015-09-08 11:58:14 +02004038{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004039 return mbedtls_ssl_session_reset_int(ssl, 0);
Manuel Pégourié-Gonnard3f09b6d2015-09-08 11:58:14 +02004040}
4041
4042/*
Paul Bakker5121ce52009-01-03 21:22:43 +00004043 * SSL set accessors
4044 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004045void mbedtls_ssl_conf_endpoint(mbedtls_ssl_config *conf, int endpoint)
Paul Bakker5121ce52009-01-03 21:22:43 +00004046{
Manuel Pégourié-Gonnardd36e33f2015-05-05 10:45:39 +02004047 conf->endpoint = endpoint;
Paul Bakker5121ce52009-01-03 21:22:43 +00004048}
4049
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004050void mbedtls_ssl_conf_transport(mbedtls_ssl_config *conf, int transport)
Manuel Pégourié-Gonnard0b1ff292014-02-06 13:04:16 +01004051{
Manuel Pégourié-Gonnardd36e33f2015-05-05 10:45:39 +02004052 conf->transport = transport;
Manuel Pégourié-Gonnard0b1ff292014-02-06 13:04:16 +01004053}
4054
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004055#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004056void mbedtls_ssl_conf_dtls_anti_replay(mbedtls_ssl_config *conf, char mode)
Manuel Pégourié-Gonnard27393132014-09-24 14:41:11 +02004057{
Manuel Pégourié-Gonnardd36e33f2015-05-05 10:45:39 +02004058 conf->anti_replay = mode;
Manuel Pégourié-Gonnard27393132014-09-24 14:41:11 +02004059}
4060#endif
4061
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004062#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004063void mbedtls_ssl_conf_dtls_badmac_limit(mbedtls_ssl_config *conf, unsigned limit)
Manuel Pégourié-Gonnardb0643d12014-10-14 18:30:36 +02004064{
Manuel Pégourié-Gonnardd36e33f2015-05-05 10:45:39 +02004065 conf->badmac_limit = limit;
Manuel Pégourié-Gonnardb0643d12014-10-14 18:30:36 +02004066}
4067#endif
4068
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004069#if defined(MBEDTLS_SSL_PROTO_DTLS)
Hanno Becker04da1892018-08-14 13:22:10 +01004070
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004071void mbedtls_ssl_set_datagram_packing(mbedtls_ssl_context *ssl,
4072 unsigned allow_packing)
Hanno Becker04da1892018-08-14 13:22:10 +01004073{
4074 ssl->disable_datagram_packing = !allow_packing;
4075}
4076
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004077void mbedtls_ssl_conf_handshake_timeout(mbedtls_ssl_config *conf,
4078 uint32_t min, uint32_t max)
Manuel Pégourié-Gonnard905dd242014-10-01 12:03:55 +02004079{
Manuel Pégourié-Gonnardd36e33f2015-05-05 10:45:39 +02004080 conf->hs_timeout_min = min;
4081 conf->hs_timeout_max = max;
Manuel Pégourié-Gonnard905dd242014-10-01 12:03:55 +02004082}
4083#endif
4084
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004085void mbedtls_ssl_conf_authmode(mbedtls_ssl_config *conf, int authmode)
Paul Bakker5121ce52009-01-03 21:22:43 +00004086{
Manuel Pégourié-Gonnardd36e33f2015-05-05 10:45:39 +02004087 conf->authmode = authmode;
Paul Bakker5121ce52009-01-03 21:22:43 +00004088}
4089
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004090#if defined(MBEDTLS_X509_CRT_PARSE_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004091void mbedtls_ssl_conf_verify(mbedtls_ssl_config *conf,
4092 int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
4093 void *p_vrfy)
Paul Bakkerb63b0af2011-01-13 17:54:59 +00004094{
Manuel Pégourié-Gonnardd36e33f2015-05-05 10:45:39 +02004095 conf->f_vrfy = f_vrfy;
4096 conf->p_vrfy = p_vrfy;
Paul Bakkerb63b0af2011-01-13 17:54:59 +00004097}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004098#endif /* MBEDTLS_X509_CRT_PARSE_C */
Paul Bakkerb63b0af2011-01-13 17:54:59 +00004099
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004100void mbedtls_ssl_conf_rng(mbedtls_ssl_config *conf,
4101 int (*f_rng)(void *, unsigned char *, size_t),
4102 void *p_rng)
Paul Bakker5121ce52009-01-03 21:22:43 +00004103{
Manuel Pégourié-Gonnard750e4d72015-05-07 12:35:38 +01004104 conf->f_rng = f_rng;
4105 conf->p_rng = p_rng;
Paul Bakker5121ce52009-01-03 21:22:43 +00004106}
4107
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004108void mbedtls_ssl_conf_dbg(mbedtls_ssl_config *conf,
4109 void (*f_dbg)(void *, int, const char *, int, const char *),
4110 void *p_dbg)
Paul Bakker5121ce52009-01-03 21:22:43 +00004111{
Manuel Pégourié-Gonnardd36e33f2015-05-05 10:45:39 +02004112 conf->f_dbg = f_dbg;
4113 conf->p_dbg = p_dbg;
Paul Bakker5121ce52009-01-03 21:22:43 +00004114}
4115
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004116void mbedtls_ssl_set_bio(mbedtls_ssl_context *ssl,
4117 void *p_bio,
4118 mbedtls_ssl_send_t *f_send,
4119 mbedtls_ssl_recv_t *f_recv,
4120 mbedtls_ssl_recv_timeout_t *f_recv_timeout)
Manuel Pégourié-Gonnard8fa6dfd2014-09-17 10:47:43 +02004121{
4122 ssl->p_bio = p_bio;
4123 ssl->f_send = f_send;
4124 ssl->f_recv = f_recv;
4125 ssl->f_recv_timeout = f_recv_timeout;
Manuel Pégourié-Gonnard97fd52c2015-05-06 15:38:52 +01004126}
4127
Manuel Pégourié-Gonnard6e7aaca2018-08-20 10:37:23 +02004128#if defined(MBEDTLS_SSL_PROTO_DTLS)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004129void mbedtls_ssl_set_mtu(mbedtls_ssl_context *ssl, uint16_t mtu)
Manuel Pégourié-Gonnard6e7aaca2018-08-20 10:37:23 +02004130{
4131 ssl->mtu = mtu;
4132}
4133#endif
4134
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004135void mbedtls_ssl_conf_read_timeout(mbedtls_ssl_config *conf, uint32_t timeout)
Manuel Pégourié-Gonnard97fd52c2015-05-06 15:38:52 +01004136{
4137 conf->read_timeout = timeout;
Manuel Pégourié-Gonnard8fa6dfd2014-09-17 10:47:43 +02004138}
4139
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004140void mbedtls_ssl_set_timer_cb(mbedtls_ssl_context *ssl,
4141 void *p_timer,
4142 mbedtls_ssl_set_timer_t *f_set_timer,
4143 mbedtls_ssl_get_timer_t *f_get_timer)
Manuel Pégourié-Gonnard2e012912015-05-12 20:55:41 +02004144{
4145 ssl->p_timer = p_timer;
4146 ssl->f_set_timer = f_set_timer;
4147 ssl->f_get_timer = f_get_timer;
Manuel Pégourié-Gonnard286a1362015-05-13 16:22:05 +02004148
4149 /* Make sure we start with no timer running */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004150 mbedtls_ssl_set_timer(ssl, 0);
Manuel Pégourié-Gonnard2e012912015-05-12 20:55:41 +02004151}
4152
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004153#if defined(MBEDTLS_SSL_SRV_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004154void mbedtls_ssl_conf_session_cache(mbedtls_ssl_config *conf,
4155 void *p_cache,
4156 int (*f_get_cache)(void *, mbedtls_ssl_session *),
4157 int (*f_set_cache)(void *, const mbedtls_ssl_session *))
Paul Bakker5121ce52009-01-03 21:22:43 +00004158{
Manuel Pégourié-Gonnard5cb33082015-05-06 18:06:26 +01004159 conf->p_cache = p_cache;
Manuel Pégourié-Gonnardd36e33f2015-05-05 10:45:39 +02004160 conf->f_get_cache = f_get_cache;
Manuel Pégourié-Gonnardd36e33f2015-05-05 10:45:39 +02004161 conf->f_set_cache = f_set_cache;
Paul Bakker5121ce52009-01-03 21:22:43 +00004162}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004163#endif /* MBEDTLS_SSL_SRV_C */
Paul Bakker5121ce52009-01-03 21:22:43 +00004164
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004165#if defined(MBEDTLS_SSL_CLI_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004166int mbedtls_ssl_set_session(mbedtls_ssl_context *ssl, const mbedtls_ssl_session *session)
Paul Bakker5121ce52009-01-03 21:22:43 +00004167{
Janos Follath865b3eb2019-12-16 11:46:15 +00004168 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard06650f62013-08-02 15:34:52 +02004169
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004170 if (ssl == NULL ||
Manuel Pégourié-Gonnard06650f62013-08-02 15:34:52 +02004171 session == NULL ||
4172 ssl->session_negotiate == NULL ||
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004173 ssl->conf->endpoint != MBEDTLS_SSL_IS_CLIENT) {
4174 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
Manuel Pégourié-Gonnard06650f62013-08-02 15:34:52 +02004175 }
4176
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004177 if ((ret = mbedtls_ssl_session_copy(ssl->session_negotiate,
4178 session)) != 0) {
4179 return ret;
4180 }
Manuel Pégourié-Gonnard06650f62013-08-02 15:34:52 +02004181
Paul Bakker0a597072012-09-25 21:55:46 +00004182 ssl->handshake->resume = 1;
Manuel Pégourié-Gonnard06650f62013-08-02 15:34:52 +02004183
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004184 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +00004185}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004186#endif /* MBEDTLS_SSL_CLI_C */
Paul Bakker5121ce52009-01-03 21:22:43 +00004187
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004188void mbedtls_ssl_conf_ciphersuites(mbedtls_ssl_config *conf,
4189 const int *ciphersuites)
Paul Bakker5121ce52009-01-03 21:22:43 +00004190{
Manuel Pégourié-Gonnardd36e33f2015-05-05 10:45:39 +02004191 conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_0] = ciphersuites;
4192 conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_1] = ciphersuites;
4193 conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_2] = ciphersuites;
4194 conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_3] = ciphersuites;
Paul Bakker8f4ddae2013-04-15 15:09:54 +02004195}
4196
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004197void mbedtls_ssl_conf_ciphersuites_for_version(mbedtls_ssl_config *conf,
4198 const int *ciphersuites,
4199 int major, int minor)
Paul Bakker8f4ddae2013-04-15 15:09:54 +02004200{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004201 if (major != MBEDTLS_SSL_MAJOR_VERSION_3) {
Paul Bakker8f4ddae2013-04-15 15:09:54 +02004202 return;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004203 }
Paul Bakker8f4ddae2013-04-15 15:09:54 +02004204
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004205 if (minor < MBEDTLS_SSL_MINOR_VERSION_0 || minor > MBEDTLS_SSL_MINOR_VERSION_3) {
Paul Bakker8f4ddae2013-04-15 15:09:54 +02004206 return;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004207 }
Paul Bakker8f4ddae2013-04-15 15:09:54 +02004208
Manuel Pégourié-Gonnardd36e33f2015-05-05 10:45:39 +02004209 conf->ciphersuite_list[minor] = ciphersuites;
Paul Bakker5121ce52009-01-03 21:22:43 +00004210}
4211
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004212#if defined(MBEDTLS_X509_CRT_PARSE_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004213void mbedtls_ssl_conf_cert_profile(mbedtls_ssl_config *conf,
4214 const mbedtls_x509_crt_profile *profile)
Manuel Pégourié-Gonnard6e3ee3a2015-06-17 10:58:20 +02004215{
4216 conf->cert_profile = profile;
4217}
4218
Manuel Pégourié-Gonnard8f618a82015-05-10 21:13:36 +02004219/* Append a new keycert entry to a (possibly empty) list */
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +02004220MBEDTLS_CHECK_RETURN_CRITICAL
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004221static int ssl_append_key_cert(mbedtls_ssl_key_cert **head,
4222 mbedtls_x509_crt *cert,
4223 mbedtls_pk_context *key)
Manuel Pégourié-Gonnard834ea852013-09-23 14:46:13 +02004224{
niisato8ee24222018-06-25 19:05:48 +09004225 mbedtls_ssl_key_cert *new_cert;
Manuel Pégourié-Gonnard834ea852013-09-23 14:46:13 +02004226
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004227 new_cert = mbedtls_calloc(1, sizeof(mbedtls_ssl_key_cert));
4228 if (new_cert == NULL) {
4229 return MBEDTLS_ERR_SSL_ALLOC_FAILED;
4230 }
Manuel Pégourié-Gonnard834ea852013-09-23 14:46:13 +02004231
niisato8ee24222018-06-25 19:05:48 +09004232 new_cert->cert = cert;
4233 new_cert->key = key;
4234 new_cert->next = NULL;
Manuel Pégourié-Gonnard834ea852013-09-23 14:46:13 +02004235
Manuel Pégourié-Gonnard8f618a82015-05-10 21:13:36 +02004236 /* Update head is the list was null, else add to the end */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004237 if (*head == NULL) {
niisato8ee24222018-06-25 19:05:48 +09004238 *head = new_cert;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004239 } else {
Manuel Pégourié-Gonnard8f618a82015-05-10 21:13:36 +02004240 mbedtls_ssl_key_cert *cur = *head;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004241 while (cur->next != NULL) {
Manuel Pégourié-Gonnard8f618a82015-05-10 21:13:36 +02004242 cur = cur->next;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004243 }
niisato8ee24222018-06-25 19:05:48 +09004244 cur->next = new_cert;
Manuel Pégourié-Gonnard834ea852013-09-23 14:46:13 +02004245 }
4246
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004247 return 0;
Manuel Pégourié-Gonnard8f618a82015-05-10 21:13:36 +02004248}
4249
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004250int mbedtls_ssl_conf_own_cert(mbedtls_ssl_config *conf,
Manuel Pégourié-Gonnard8f618a82015-05-10 21:13:36 +02004251 mbedtls_x509_crt *own_cert,
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004252 mbedtls_pk_context *pk_key)
Manuel Pégourié-Gonnard8f618a82015-05-10 21:13:36 +02004253{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004254 return ssl_append_key_cert(&conf->key_cert, own_cert, pk_key);
Manuel Pégourié-Gonnard834ea852013-09-23 14:46:13 +02004255}
4256
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004257void mbedtls_ssl_conf_ca_chain(mbedtls_ssl_config *conf,
Manuel Pégourié-Gonnardbc2b7712015-05-06 11:14:19 +01004258 mbedtls_x509_crt *ca_chain,
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004259 mbedtls_x509_crl *ca_crl)
Paul Bakker5121ce52009-01-03 21:22:43 +00004260{
Manuel Pégourié-Gonnardbc2b7712015-05-06 11:14:19 +01004261 conf->ca_chain = ca_chain;
4262 conf->ca_crl = ca_crl;
Hanno Becker5adaad92019-03-27 16:54:37 +00004263
4264#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
4265 /* mbedtls_ssl_conf_ca_chain() and mbedtls_ssl_conf_ca_cb()
4266 * cannot be used together. */
4267 conf->f_ca_cb = NULL;
4268 conf->p_ca_cb = NULL;
4269#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */
Paul Bakker5121ce52009-01-03 21:22:43 +00004270}
Hanno Becker5adaad92019-03-27 16:54:37 +00004271
4272#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004273void mbedtls_ssl_conf_ca_cb(mbedtls_ssl_config *conf,
4274 mbedtls_x509_crt_ca_cb_t f_ca_cb,
4275 void *p_ca_cb)
Hanno Becker5adaad92019-03-27 16:54:37 +00004276{
4277 conf->f_ca_cb = f_ca_cb;
4278 conf->p_ca_cb = p_ca_cb;
4279
4280 /* mbedtls_ssl_conf_ca_chain() and mbedtls_ssl_conf_ca_cb()
4281 * cannot be used together. */
4282 conf->ca_chain = NULL;
4283 conf->ca_crl = NULL;
4284}
4285#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004286#endif /* MBEDTLS_X509_CRT_PARSE_C */
Paul Bakkereb2c6582012-09-27 19:15:01 +00004287
Manuel Pégourié-Gonnard1af6c852015-05-10 23:10:37 +02004288#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004289int mbedtls_ssl_set_hs_own_cert(mbedtls_ssl_context *ssl,
4290 mbedtls_x509_crt *own_cert,
4291 mbedtls_pk_context *pk_key)
Manuel Pégourié-Gonnard1af6c852015-05-10 23:10:37 +02004292{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004293 return ssl_append_key_cert(&ssl->handshake->sni_key_cert,
4294 own_cert, pk_key);
Manuel Pégourié-Gonnard1af6c852015-05-10 23:10:37 +02004295}
Manuel Pégourié-Gonnard22bfa4b2015-05-11 08:46:37 +02004296
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004297void mbedtls_ssl_set_hs_ca_chain(mbedtls_ssl_context *ssl,
4298 mbedtls_x509_crt *ca_chain,
4299 mbedtls_x509_crl *ca_crl)
Manuel Pégourié-Gonnard22bfa4b2015-05-11 08:46:37 +02004300{
4301 ssl->handshake->sni_ca_chain = ca_chain;
4302 ssl->handshake->sni_ca_crl = ca_crl;
4303}
Manuel Pégourié-Gonnardcdc26ae2015-06-19 12:16:31 +02004304
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004305void mbedtls_ssl_set_hs_authmode(mbedtls_ssl_context *ssl,
4306 int authmode)
Manuel Pégourié-Gonnardcdc26ae2015-06-19 12:16:31 +02004307{
4308 ssl->handshake->sni_authmode = authmode;
4309}
Manuel Pégourié-Gonnard1af6c852015-05-10 23:10:37 +02004310#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
4311
Hanno Becker8927c832019-04-03 12:52:50 +01004312#if defined(MBEDTLS_X509_CRT_PARSE_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004313void mbedtls_ssl_set_verify(mbedtls_ssl_context *ssl,
4314 int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
4315 void *p_vrfy)
Hanno Becker8927c832019-04-03 12:52:50 +01004316{
4317 ssl->f_vrfy = f_vrfy;
4318 ssl->p_vrfy = p_vrfy;
4319}
4320#endif
4321
Manuel Pégourié-Gonnardeef142d2015-09-16 10:05:04 +02004322#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
Manuel Pégourié-Gonnard7002f4a2015-09-15 12:43:43 +02004323/*
4324 * Set EC J-PAKE password for current handshake
4325 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004326int mbedtls_ssl_set_hs_ecjpake_password(mbedtls_ssl_context *ssl,
4327 const unsigned char *pw,
4328 size_t pw_len)
Manuel Pégourié-Gonnard7002f4a2015-09-15 12:43:43 +02004329{
4330 mbedtls_ecjpake_role role;
4331
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004332 if (ssl->handshake == NULL || ssl->conf == NULL) {
4333 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
4334 }
Manuel Pégourié-Gonnard7002f4a2015-09-15 12:43:43 +02004335
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004336 if (ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER) {
Manuel Pégourié-Gonnard7002f4a2015-09-15 12:43:43 +02004337 role = MBEDTLS_ECJPAKE_SERVER;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004338 } else {
Manuel Pégourié-Gonnard7002f4a2015-09-15 12:43:43 +02004339 role = MBEDTLS_ECJPAKE_CLIENT;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004340 }
Manuel Pégourié-Gonnard7002f4a2015-09-15 12:43:43 +02004341
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004342 return mbedtls_ecjpake_setup(&ssl->handshake->ecjpake_ctx,
4343 role,
4344 MBEDTLS_MD_SHA256,
4345 MBEDTLS_ECP_DP_SECP256R1,
4346 pw, pw_len);
Manuel Pégourié-Gonnard7002f4a2015-09-15 12:43:43 +02004347}
Manuel Pégourié-Gonnardeef142d2015-09-16 10:05:04 +02004348#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
Manuel Pégourié-Gonnard7002f4a2015-09-15 12:43:43 +02004349
Gilles Peskineeccd8882020-03-10 12:19:08 +01004350#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
Hanno Beckerd20a8ca2018-10-22 15:31:26 +01004351
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004352static void ssl_conf_remove_psk(mbedtls_ssl_config *conf)
Hanno Beckerd20a8ca2018-10-22 15:31:26 +01004353{
4354 /* Remove reference to existing PSK, if any. */
4355#if defined(MBEDTLS_USE_PSA_CRYPTO)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004356 if (!mbedtls_svc_key_id_is_null(conf->psk_opaque)) {
Hanno Beckerd20a8ca2018-10-22 15:31:26 +01004357 /* The maintenance of the PSK key slot is the
4358 * user's responsibility. */
Ronald Croncf56a0a2020-08-04 09:51:30 +02004359 conf->psk_opaque = MBEDTLS_SVC_KEY_ID_INIT;
Hanno Beckerd20a8ca2018-10-22 15:31:26 +01004360 }
Hanno Beckera63ac3f2018-11-05 12:47:16 +00004361 /* This and the following branch should never
Tom Cosgrove49f99bc2022-12-04 16:44:21 +00004362 * be taken simultaneously as we maintain the
Hanno Beckera63ac3f2018-11-05 12:47:16 +00004363 * invariant that raw and opaque PSKs are never
4364 * configured simultaneously. As a safeguard,
4365 * though, `else` is omitted here. */
Hanno Beckerd20a8ca2018-10-22 15:31:26 +01004366#endif /* MBEDTLS_USE_PSA_CRYPTO */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004367 if (conf->psk != NULL) {
4368 mbedtls_platform_zeroize(conf->psk, conf->psk_len);
Hanno Beckerd20a8ca2018-10-22 15:31:26 +01004369
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004370 mbedtls_free(conf->psk);
Hanno Beckerd20a8ca2018-10-22 15:31:26 +01004371 conf->psk = NULL;
4372 conf->psk_len = 0;
4373 }
4374
4375 /* Remove reference to PSK identity, if any. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004376 if (conf->psk_identity != NULL) {
4377 mbedtls_free(conf->psk_identity);
Hanno Beckerd20a8ca2018-10-22 15:31:26 +01004378 conf->psk_identity = NULL;
4379 conf->psk_identity_len = 0;
4380 }
4381}
4382
Hanno Becker7390c712018-11-15 13:33:04 +00004383/* This function assumes that PSK identity in the SSL config is unset.
4384 * It checks that the provided identity is well-formed and attempts
4385 * to make a copy of it in the SSL config.
4386 * On failure, the PSK identity in the config remains unset. */
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +02004387MBEDTLS_CHECK_RETURN_CRITICAL
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004388static int ssl_conf_set_psk_identity(mbedtls_ssl_config *conf,
4389 unsigned char const *psk_identity,
4390 size_t psk_identity_len)
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02004391{
Manuel Pégourié-Gonnardc6b5d832015-08-27 16:37:35 +02004392 /* Identity len will be encoded on two bytes */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004393 if (psk_identity == NULL ||
4394 (psk_identity_len >> 16) != 0 ||
4395 psk_identity_len > MBEDTLS_SSL_OUT_CONTENT_LEN) {
4396 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
Manuel Pégourié-Gonnardc6b5d832015-08-27 16:37:35 +02004397 }
4398
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004399 conf->psk_identity = mbedtls_calloc(1, psk_identity_len);
4400 if (conf->psk_identity == NULL) {
4401 return MBEDTLS_ERR_SSL_ALLOC_FAILED;
4402 }
Paul Bakker6db455e2013-09-18 17:29:31 +02004403
Manuel Pégourié-Gonnard120fdbd2015-05-07 17:07:50 +01004404 conf->psk_identity_len = psk_identity_len;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004405 memcpy(conf->psk_identity, psk_identity, conf->psk_identity_len);
Paul Bakker5ad403f2013-09-18 21:21:30 +02004406
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004407 return 0;
Paul Bakker6db455e2013-09-18 17:29:31 +02004408}
4409
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004410int mbedtls_ssl_conf_psk(mbedtls_ssl_config *conf,
4411 const unsigned char *psk, size_t psk_len,
4412 const unsigned char *psk_identity, size_t psk_identity_len)
Hanno Becker7390c712018-11-15 13:33:04 +00004413{
Janos Follath865b3eb2019-12-16 11:46:15 +00004414 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Hanno Becker7390c712018-11-15 13:33:04 +00004415 /* Remove opaque/raw PSK + PSK Identity */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004416 ssl_conf_remove_psk(conf);
Hanno Becker7390c712018-11-15 13:33:04 +00004417
4418 /* Check and set raw PSK */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004419 if (psk == NULL) {
4420 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
4421 }
4422 if (psk_len == 0) {
4423 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
4424 }
4425 if (psk_len > MBEDTLS_PSK_MAX_LEN) {
4426 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
4427 }
Piotr Nowicki9926eaf2019-11-20 14:54:36 +01004428
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004429 if ((conf->psk = mbedtls_calloc(1, psk_len)) == NULL) {
4430 return MBEDTLS_ERR_SSL_ALLOC_FAILED;
4431 }
Hanno Becker7390c712018-11-15 13:33:04 +00004432 conf->psk_len = psk_len;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004433 memcpy(conf->psk, psk, conf->psk_len);
Hanno Becker7390c712018-11-15 13:33:04 +00004434
4435 /* Check and set PSK Identity */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004436 ret = ssl_conf_set_psk_identity(conf, psk_identity, psk_identity_len);
4437 if (ret != 0) {
4438 ssl_conf_remove_psk(conf);
4439 }
Hanno Becker7390c712018-11-15 13:33:04 +00004440
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004441 return ret;
Hanno Becker7390c712018-11-15 13:33:04 +00004442}
4443
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004444static void ssl_remove_psk(mbedtls_ssl_context *ssl)
Hanno Beckerd20a8ca2018-10-22 15:31:26 +01004445{
4446#if defined(MBEDTLS_USE_PSA_CRYPTO)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004447 if (!mbedtls_svc_key_id_is_null(ssl->handshake->psk_opaque)) {
Ronald Croncf56a0a2020-08-04 09:51:30 +02004448 ssl->handshake->psk_opaque = MBEDTLS_SVC_KEY_ID_INIT;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004449 } else
Hanno Beckerd20a8ca2018-10-22 15:31:26 +01004450#endif /* MBEDTLS_USE_PSA_CRYPTO */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004451 if (ssl->handshake->psk != NULL) {
4452 mbedtls_platform_zeroize(ssl->handshake->psk,
4453 ssl->handshake->psk_len);
4454 mbedtls_free(ssl->handshake->psk);
Hanno Beckerd20a8ca2018-10-22 15:31:26 +01004455 ssl->handshake->psk_len = 0;
4456 }
4457}
4458
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004459int mbedtls_ssl_set_hs_psk(mbedtls_ssl_context *ssl,
4460 const unsigned char *psk, size_t psk_len)
Manuel Pégourié-Gonnard4b682962015-05-07 15:59:54 +01004461{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004462 if (psk == NULL || ssl->handshake == NULL) {
4463 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
4464 }
Manuel Pégourié-Gonnard4b682962015-05-07 15:59:54 +01004465
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004466 if (psk_len > MBEDTLS_PSK_MAX_LEN) {
4467 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
4468 }
Manuel Pégourié-Gonnard4b682962015-05-07 15:59:54 +01004469
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004470 ssl_remove_psk(ssl);
Manuel Pégourié-Gonnard4b682962015-05-07 15:59:54 +01004471
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004472 if ((ssl->handshake->psk = mbedtls_calloc(1, psk_len)) == NULL) {
4473 return MBEDTLS_ERR_SSL_ALLOC_FAILED;
4474 }
Manuel Pégourié-Gonnard4b682962015-05-07 15:59:54 +01004475
4476 ssl->handshake->psk_len = psk_len;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004477 memcpy(ssl->handshake->psk, psk, ssl->handshake->psk_len);
Manuel Pégourié-Gonnard4b682962015-05-07 15:59:54 +01004478
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004479 return 0;
Manuel Pégourié-Gonnard4b682962015-05-07 15:59:54 +01004480}
4481
Hanno Beckerd20a8ca2018-10-22 15:31:26 +01004482#if defined(MBEDTLS_USE_PSA_CRYPTO)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004483int mbedtls_ssl_conf_psk_opaque(mbedtls_ssl_config *conf,
4484 psa_key_id_t psk,
4485 const unsigned char *psk_identity,
4486 size_t psk_identity_len)
Hanno Beckerd20a8ca2018-10-22 15:31:26 +01004487{
Janos Follath865b3eb2019-12-16 11:46:15 +00004488 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Hanno Becker7390c712018-11-15 13:33:04 +00004489 /* Clear opaque/raw PSK + PSK Identity, if present. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004490 ssl_conf_remove_psk(conf);
Hanno Beckerd20a8ca2018-10-22 15:31:26 +01004491
Hanno Becker7390c712018-11-15 13:33:04 +00004492 /* Check and set opaque PSK */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004493 if (mbedtls_svc_key_id_is_null(psk)) {
4494 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
4495 }
Ronald Croncf56a0a2020-08-04 09:51:30 +02004496 conf->psk_opaque = psk;
Hanno Becker7390c712018-11-15 13:33:04 +00004497
4498 /* Check and set PSK Identity */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004499 ret = ssl_conf_set_psk_identity(conf, psk_identity,
4500 psk_identity_len);
4501 if (ret != 0) {
4502 ssl_conf_remove_psk(conf);
4503 }
Hanno Becker7390c712018-11-15 13:33:04 +00004504
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004505 return ret;
Hanno Beckerd20a8ca2018-10-22 15:31:26 +01004506}
4507
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004508int mbedtls_ssl_set_hs_psk_opaque(mbedtls_ssl_context *ssl,
4509 psa_key_id_t psk)
Hanno Beckerd20a8ca2018-10-22 15:31:26 +01004510{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004511 if ((mbedtls_svc_key_id_is_null(psk)) ||
4512 (ssl->handshake == NULL)) {
4513 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
4514 }
Hanno Beckerd20a8ca2018-10-22 15:31:26 +01004515
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004516 ssl_remove_psk(ssl);
Ronald Croncf56a0a2020-08-04 09:51:30 +02004517 ssl->handshake->psk_opaque = psk;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004518 return 0;
Hanno Beckerd20a8ca2018-10-22 15:31:26 +01004519}
4520#endif /* MBEDTLS_USE_PSA_CRYPTO */
4521
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004522void mbedtls_ssl_conf_psk_cb(mbedtls_ssl_config *conf,
4523 int (*f_psk)(void *, mbedtls_ssl_context *, const unsigned char *,
4524 size_t),
4525 void *p_psk)
Paul Bakker6db455e2013-09-18 17:29:31 +02004526{
Manuel Pégourié-Gonnardd36e33f2015-05-05 10:45:39 +02004527 conf->f_psk = f_psk;
4528 conf->p_psk = p_psk;
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02004529}
Gilles Peskineeccd8882020-03-10 12:19:08 +01004530#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
Paul Bakker43b7e352011-01-18 15:27:19 +00004531
Manuel Pégourié-Gonnardcf141ca2015-05-20 10:35:51 +02004532#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_SRV_C)
Hanno Becker470a8c42017-10-04 15:28:46 +01004533
4534#if !defined(MBEDTLS_DEPRECATED_REMOVED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004535int mbedtls_ssl_conf_dh_param(mbedtls_ssl_config *conf, const char *dhm_P, const char *dhm_G)
Paul Bakker5121ce52009-01-03 21:22:43 +00004536{
Janos Follath865b3eb2019-12-16 11:46:15 +00004537 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +00004538
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004539 if ((ret = mbedtls_mpi_read_string(&conf->dhm_P, 16, dhm_P)) != 0 ||
4540 (ret = mbedtls_mpi_read_string(&conf->dhm_G, 16, dhm_G)) != 0) {
4541 mbedtls_mpi_free(&conf->dhm_P);
4542 mbedtls_mpi_free(&conf->dhm_G);
4543 return ret;
Manuel Pégourié-Gonnard1028b742015-05-06 17:33:07 +01004544 }
Paul Bakker5121ce52009-01-03 21:22:43 +00004545
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004546 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +00004547}
Hanno Becker470a8c42017-10-04 15:28:46 +01004548#endif /* MBEDTLS_DEPRECATED_REMOVED */
Paul Bakker5121ce52009-01-03 21:22:43 +00004549
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004550int mbedtls_ssl_conf_dh_param_bin(mbedtls_ssl_config *conf,
4551 const unsigned char *dhm_P, size_t P_len,
4552 const unsigned char *dhm_G, size_t G_len)
Hanno Beckera90658f2017-10-04 15:29:08 +01004553{
Janos Follath865b3eb2019-12-16 11:46:15 +00004554 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Hanno Beckera90658f2017-10-04 15:29:08 +01004555
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004556 mbedtls_mpi_free(&conf->dhm_P);
4557 mbedtls_mpi_free(&conf->dhm_G);
Glenn Straussde081ce2021-12-20 01:43:17 -05004558
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004559 if ((ret = mbedtls_mpi_read_binary(&conf->dhm_P, dhm_P, P_len)) != 0 ||
4560 (ret = mbedtls_mpi_read_binary(&conf->dhm_G, dhm_G, G_len)) != 0) {
4561 mbedtls_mpi_free(&conf->dhm_P);
4562 mbedtls_mpi_free(&conf->dhm_G);
4563 return ret;
Hanno Beckera90658f2017-10-04 15:29:08 +01004564 }
4565
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004566 return 0;
Hanno Beckera90658f2017-10-04 15:29:08 +01004567}
Paul Bakker5121ce52009-01-03 21:22:43 +00004568
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004569int mbedtls_ssl_conf_dh_param_ctx(mbedtls_ssl_config *conf, mbedtls_dhm_context *dhm_ctx)
Paul Bakker1b57b062011-01-06 15:48:19 +00004570{
Janos Follath865b3eb2019-12-16 11:46:15 +00004571 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker1b57b062011-01-06 15:48:19 +00004572
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004573 mbedtls_mpi_free(&conf->dhm_P);
4574 mbedtls_mpi_free(&conf->dhm_G);
Glenn Straussde081ce2021-12-20 01:43:17 -05004575
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004576 if ((ret = mbedtls_mpi_copy(&conf->dhm_P, &dhm_ctx->P)) != 0 ||
4577 (ret = mbedtls_mpi_copy(&conf->dhm_G, &dhm_ctx->G)) != 0) {
4578 mbedtls_mpi_free(&conf->dhm_P);
4579 mbedtls_mpi_free(&conf->dhm_G);
4580 return ret;
Manuel Pégourié-Gonnard1028b742015-05-06 17:33:07 +01004581 }
Paul Bakker1b57b062011-01-06 15:48:19 +00004582
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004583 return 0;
Paul Bakker1b57b062011-01-06 15:48:19 +00004584}
Manuel Pégourié-Gonnardcf141ca2015-05-20 10:35:51 +02004585#endif /* MBEDTLS_DHM_C && MBEDTLS_SSL_SRV_C */
Paul Bakker1b57b062011-01-06 15:48:19 +00004586
Manuel Pégourié-Gonnardbd990d62015-06-11 14:49:42 +02004587#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_CLI_C)
4588/*
4589 * Set the minimum length for Diffie-Hellman parameters
4590 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004591void mbedtls_ssl_conf_dhm_min_bitlen(mbedtls_ssl_config *conf,
4592 unsigned int bitlen)
Manuel Pégourié-Gonnardbd990d62015-06-11 14:49:42 +02004593{
4594 conf->dhm_min_bitlen = bitlen;
4595}
4596#endif /* MBEDTLS_DHM_C && MBEDTLS_SSL_CLI_C */
4597
Gilles Peskineeccd8882020-03-10 12:19:08 +01004598#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
Manuel Pégourié-Gonnard36a8b572015-06-17 12:43:26 +02004599/*
4600 * Set allowed/preferred hashes for handshake signatures
4601 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004602void mbedtls_ssl_conf_sig_hashes(mbedtls_ssl_config *conf,
4603 const int *hashes)
Manuel Pégourié-Gonnard36a8b572015-06-17 12:43:26 +02004604{
4605 conf->sig_hashes = hashes;
4606}
Gilles Peskineeccd8882020-03-10 12:19:08 +01004607#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
Manuel Pégourié-Gonnard36a8b572015-06-17 12:43:26 +02004608
Manuel Pégourié-Gonnardb541da62015-06-17 11:43:30 +02004609#if defined(MBEDTLS_ECP_C)
Manuel Pégourié-Gonnard7f38ed02014-02-04 15:52:33 +01004610/*
4611 * Set the allowed elliptic curves
4612 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004613void mbedtls_ssl_conf_curves(mbedtls_ssl_config *conf,
4614 const mbedtls_ecp_group_id *curve_list)
Manuel Pégourié-Gonnard7f38ed02014-02-04 15:52:33 +01004615{
Manuel Pégourié-Gonnardd36e33f2015-05-05 10:45:39 +02004616 conf->curve_list = curve_list;
Manuel Pégourié-Gonnard7f38ed02014-02-04 15:52:33 +01004617}
Hanno Becker947194e2017-04-07 13:25:49 +01004618#endif /* MBEDTLS_ECP_C */
Manuel Pégourié-Gonnard7f38ed02014-02-04 15:52:33 +01004619
Manuel Pégourié-Gonnardbc2b7712015-05-06 11:14:19 +01004620#if defined(MBEDTLS_X509_CRT_PARSE_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004621int mbedtls_ssl_set_hostname(mbedtls_ssl_context *ssl, const char *hostname)
Paul Bakker5121ce52009-01-03 21:22:43 +00004622{
Hanno Becker947194e2017-04-07 13:25:49 +01004623 /* Initialize to suppress unnecessary compiler warning */
4624 size_t hostname_len = 0;
4625
4626 /* Check if new hostname is valid before
4627 * making any change to current one */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004628 if (hostname != NULL) {
4629 hostname_len = strlen(hostname);
Hanno Becker947194e2017-04-07 13:25:49 +01004630
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004631 if (hostname_len > MBEDTLS_SSL_MAX_HOST_NAME_LEN) {
4632 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
4633 }
Hanno Becker947194e2017-04-07 13:25:49 +01004634 }
4635
4636 /* Now it's clear that we will overwrite the old hostname,
4637 * so we can free it safely */
4638
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004639 if (ssl->hostname != NULL) {
4640 mbedtls_platform_zeroize(ssl->hostname, strlen(ssl->hostname));
4641 mbedtls_free(ssl->hostname);
Hanno Becker947194e2017-04-07 13:25:49 +01004642 }
4643
4644 /* Passing NULL as hostname shall clear the old one */
Manuel Pégourié-Gonnardba26c242015-05-06 10:47:06 +01004645
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004646 if (hostname == NULL) {
Hanno Becker947194e2017-04-07 13:25:49 +01004647 ssl->hostname = NULL;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004648 } else {
4649 ssl->hostname = mbedtls_calloc(1, hostname_len + 1);
4650 if (ssl->hostname == NULL) {
4651 return MBEDTLS_ERR_SSL_ALLOC_FAILED;
4652 }
Paul Bakker75c1a6f2013-08-19 14:25:29 +02004653
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004654 memcpy(ssl->hostname, hostname, hostname_len);
Paul Bakker75c1a6f2013-08-19 14:25:29 +02004655
Hanno Becker947194e2017-04-07 13:25:49 +01004656 ssl->hostname[hostname_len] = '\0';
4657 }
Paul Bakker5121ce52009-01-03 21:22:43 +00004658
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004659 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +00004660}
Hanno Becker1a9a51c2017-04-07 13:02:16 +01004661#endif /* MBEDTLS_X509_CRT_PARSE_C */
Paul Bakker5121ce52009-01-03 21:22:43 +00004662
Manuel Pégourié-Gonnardbc2b7712015-05-06 11:14:19 +01004663#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004664void mbedtls_ssl_conf_sni(mbedtls_ssl_config *conf,
4665 int (*f_sni)(void *, mbedtls_ssl_context *,
4666 const unsigned char *, size_t),
4667 void *p_sni)
Paul Bakker5701cdc2012-09-27 21:49:42 +00004668{
Manuel Pégourié-Gonnardd36e33f2015-05-05 10:45:39 +02004669 conf->f_sni = f_sni;
4670 conf->p_sni = p_sni;
Paul Bakker5701cdc2012-09-27 21:49:42 +00004671}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004672#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
Paul Bakker5701cdc2012-09-27 21:49:42 +00004673
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004674#if defined(MBEDTLS_SSL_ALPN)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004675int mbedtls_ssl_conf_alpn_protocols(mbedtls_ssl_config *conf, const char **protos)
Manuel Pégourié-Gonnard7e250d42014-04-04 16:08:41 +02004676{
Manuel Pégourié-Gonnard0b874dc2014-04-07 10:57:45 +02004677 size_t cur_len, tot_len;
4678 const char **p;
4679
4680 /*
Brian J Murray1903fb32016-11-06 04:45:15 -08004681 * RFC 7301 3.1: "Empty strings MUST NOT be included and byte strings
4682 * MUST NOT be truncated."
4683 * We check lengths now rather than later.
Manuel Pégourié-Gonnard0b874dc2014-04-07 10:57:45 +02004684 */
4685 tot_len = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004686 for (p = protos; *p != NULL; p++) {
4687 cur_len = strlen(*p);
Manuel Pégourié-Gonnard0b874dc2014-04-07 10:57:45 +02004688 tot_len += cur_len;
4689
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004690 if ((cur_len == 0) ||
4691 (cur_len > MBEDTLS_SSL_MAX_ALPN_NAME_LEN) ||
4692 (tot_len > MBEDTLS_SSL_MAX_ALPN_LIST_LEN)) {
4693 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
4694 }
Manuel Pégourié-Gonnard0b874dc2014-04-07 10:57:45 +02004695 }
4696
Manuel Pégourié-Gonnardd36e33f2015-05-05 10:45:39 +02004697 conf->alpn_list = protos;
Manuel Pégourié-Gonnard0b874dc2014-04-07 10:57:45 +02004698
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004699 return 0;
Manuel Pégourié-Gonnard7e250d42014-04-04 16:08:41 +02004700}
4701
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004702const char *mbedtls_ssl_get_alpn_protocol(const mbedtls_ssl_context *ssl)
Manuel Pégourié-Gonnard7e250d42014-04-04 16:08:41 +02004703{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004704 return ssl->alpn_chosen;
Manuel Pégourié-Gonnard7e250d42014-04-04 16:08:41 +02004705}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004706#endif /* MBEDTLS_SSL_ALPN */
Manuel Pégourié-Gonnard7e250d42014-04-04 16:08:41 +02004707
Johan Pascalb62bb512015-12-03 21:56:45 +01004708#if defined(MBEDTLS_SSL_DTLS_SRTP)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004709void mbedtls_ssl_conf_srtp_mki_value_supported(mbedtls_ssl_config *conf,
4710 int support_mki_value)
Ron Eldor591f1622018-01-22 12:30:04 +02004711{
4712 conf->dtls_srtp_mki_support = support_mki_value;
4713}
4714
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004715int mbedtls_ssl_dtls_srtp_set_mki_value(mbedtls_ssl_context *ssl,
4716 unsigned char *mki_value,
4717 uint16_t mki_len)
Ron Eldor591f1622018-01-22 12:30:04 +02004718{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004719 if (mki_len > MBEDTLS_TLS_SRTP_MAX_MKI_LENGTH) {
4720 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
Ron Eldora9788042018-12-05 11:04:31 +02004721 }
Ron Eldor591f1622018-01-22 12:30:04 +02004722
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004723 if (ssl->conf->dtls_srtp_mki_support == MBEDTLS_SSL_DTLS_SRTP_MKI_UNSUPPORTED) {
4724 return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
Ron Eldora9788042018-12-05 11:04:31 +02004725 }
Ron Eldor591f1622018-01-22 12:30:04 +02004726
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004727 memcpy(ssl->dtls_srtp_info.mki_value, mki_value, mki_len);
Ron Eldor591f1622018-01-22 12:30:04 +02004728 ssl->dtls_srtp_info.mki_len = mki_len;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004729 return 0;
Ron Eldor591f1622018-01-22 12:30:04 +02004730}
4731
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004732int mbedtls_ssl_conf_dtls_srtp_protection_profiles(mbedtls_ssl_config *conf,
4733 const mbedtls_ssl_srtp_profile *profiles)
Johan Pascalb62bb512015-12-03 21:56:45 +01004734{
Johan Pascal253d0262020-09-22 13:04:45 +02004735 const mbedtls_ssl_srtp_profile *p;
4736 size_t list_size = 0;
Johan Pascalb62bb512015-12-03 21:56:45 +01004737
Johan Pascal253d0262020-09-22 13:04:45 +02004738 /* check the profiles list: all entry must be valid,
4739 * its size cannot be more than the total number of supported profiles, currently 4 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004740 for (p = profiles; *p != MBEDTLS_TLS_SRTP_UNSET &&
4741 list_size <= MBEDTLS_TLS_SRTP_MAX_PROFILE_LIST_LENGTH;
4742 p++) {
4743 if (mbedtls_ssl_check_srtp_profile_value(*p) != MBEDTLS_TLS_SRTP_UNSET) {
Johan Pascal76fdf1d2020-10-22 23:31:00 +02004744 list_size++;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004745 } else {
Johan Pascal76fdf1d2020-10-22 23:31:00 +02004746 /* unsupported value, stop parsing and set the size to an error value */
4747 list_size = MBEDTLS_TLS_SRTP_MAX_PROFILE_LIST_LENGTH + 1;
Johan Pascalb62bb512015-12-03 21:56:45 +01004748 }
4749 }
4750
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004751 if (list_size > MBEDTLS_TLS_SRTP_MAX_PROFILE_LIST_LENGTH) {
4752 conf->dtls_srtp_profile_list = NULL;
4753 conf->dtls_srtp_profile_list_len = 0;
4754 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
Johan Pascal253d0262020-09-22 13:04:45 +02004755 }
4756
Johan Pascal9bc97ca2020-09-21 23:44:45 +02004757 conf->dtls_srtp_profile_list = profiles;
Johan Pascal253d0262020-09-22 13:04:45 +02004758 conf->dtls_srtp_profile_list_len = list_size;
Johan Pascalb62bb512015-12-03 21:56:45 +01004759
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004760 return 0;
Johan Pascalb62bb512015-12-03 21:56:45 +01004761}
4762
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004763void mbedtls_ssl_get_dtls_srtp_negotiation_result(const mbedtls_ssl_context *ssl,
4764 mbedtls_dtls_srtp_info *dtls_srtp_info)
Johan Pascalb62bb512015-12-03 21:56:45 +01004765{
Johan Pascal2258a4f2020-10-28 13:53:09 +01004766 dtls_srtp_info->chosen_dtls_srtp_profile = ssl->dtls_srtp_info.chosen_dtls_srtp_profile;
4767 /* do not copy the mki value if there is no chosen profile */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004768 if (dtls_srtp_info->chosen_dtls_srtp_profile == MBEDTLS_TLS_SRTP_UNSET) {
Johan Pascal2258a4f2020-10-28 13:53:09 +01004769 dtls_srtp_info->mki_len = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004770 } else {
Johan Pascal2258a4f2020-10-28 13:53:09 +01004771 dtls_srtp_info->mki_len = ssl->dtls_srtp_info.mki_len;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004772 memcpy(dtls_srtp_info->mki_value, ssl->dtls_srtp_info.mki_value,
4773 ssl->dtls_srtp_info.mki_len);
Johan Pascal2258a4f2020-10-28 13:53:09 +01004774 }
Johan Pascalb62bb512015-12-03 21:56:45 +01004775}
Johan Pascalb62bb512015-12-03 21:56:45 +01004776#endif /* MBEDTLS_SSL_DTLS_SRTP */
4777
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004778void mbedtls_ssl_conf_max_version(mbedtls_ssl_config *conf, int major, int minor)
Paul Bakker490ecc82011-10-06 13:04:09 +00004779{
Manuel Pégourié-Gonnardd36e33f2015-05-05 10:45:39 +02004780 conf->max_major_ver = major;
4781 conf->max_minor_ver = minor;
Paul Bakker490ecc82011-10-06 13:04:09 +00004782}
4783
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004784void mbedtls_ssl_conf_min_version(mbedtls_ssl_config *conf, int major, int minor)
Paul Bakker1d29fb52012-09-28 13:28:45 +00004785{
Manuel Pégourié-Gonnardd36e33f2015-05-05 10:45:39 +02004786 conf->min_major_ver = major;
4787 conf->min_minor_ver = minor;
Paul Bakker1d29fb52012-09-28 13:28:45 +00004788}
4789
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004790#if defined(MBEDTLS_SSL_FALLBACK_SCSV) && defined(MBEDTLS_SSL_CLI_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004791void mbedtls_ssl_conf_fallback(mbedtls_ssl_config *conf, char fallback)
Manuel Pégourié-Gonnard1cbd39d2014-10-20 13:34:59 +02004792{
Manuel Pégourié-Gonnard684b0592015-05-06 09:27:31 +01004793 conf->fallback = fallback;
Manuel Pégourié-Gonnard1cbd39d2014-10-20 13:34:59 +02004794}
4795#endif
4796
Janos Follath088ce432017-04-10 12:42:31 +01004797#if defined(MBEDTLS_SSL_SRV_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004798void mbedtls_ssl_conf_cert_req_ca_list(mbedtls_ssl_config *conf,
4799 char cert_req_ca_list)
Janos Follath088ce432017-04-10 12:42:31 +01004800{
4801 conf->cert_req_ca_list = cert_req_ca_list;
4802}
4803#endif
4804
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004805#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004806void mbedtls_ssl_conf_encrypt_then_mac(mbedtls_ssl_config *conf, char etm)
Manuel Pégourié-Gonnard699cafa2014-10-27 13:57:03 +01004807{
Manuel Pégourié-Gonnardd36e33f2015-05-05 10:45:39 +02004808 conf->encrypt_then_mac = etm;
Manuel Pégourié-Gonnard699cafa2014-10-27 13:57:03 +01004809}
4810#endif
4811
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004812#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004813void mbedtls_ssl_conf_extended_master_secret(mbedtls_ssl_config *conf, char ems)
Manuel Pégourié-Gonnard367381f2014-10-20 18:40:56 +02004814{
Manuel Pégourié-Gonnardd36e33f2015-05-05 10:45:39 +02004815 conf->extended_ms = ems;
Manuel Pégourié-Gonnard367381f2014-10-20 18:40:56 +02004816}
4817#endif
4818
Manuel Pégourié-Gonnard66dc5552015-05-14 12:28:21 +02004819#if defined(MBEDTLS_ARC4_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004820void mbedtls_ssl_conf_arc4_support(mbedtls_ssl_config *conf, char arc4)
Manuel Pégourié-Gonnardbd47a582015-01-12 13:43:29 +01004821{
Manuel Pégourié-Gonnardd36e33f2015-05-05 10:45:39 +02004822 conf->arc4_disabled = arc4;
Manuel Pégourié-Gonnardbd47a582015-01-12 13:43:29 +01004823}
Manuel Pégourié-Gonnard66dc5552015-05-14 12:28:21 +02004824#endif
Manuel Pégourié-Gonnardbd47a582015-01-12 13:43:29 +01004825
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004826#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004827int mbedtls_ssl_conf_max_frag_len(mbedtls_ssl_config *conf, unsigned char mfl_code)
Manuel Pégourié-Gonnard8b464592013-07-16 12:45:26 +02004828{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004829 if (mfl_code >= MBEDTLS_SSL_MAX_FRAG_LEN_INVALID ||
4830 ssl_mfl_code_to_length(mfl_code) > MBEDTLS_TLS_EXT_ADV_CONTENT_LEN) {
4831 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
Manuel Pégourié-Gonnard8b464592013-07-16 12:45:26 +02004832 }
4833
Manuel Pégourié-Gonnard6bf89d62015-05-05 17:01:57 +01004834 conf->mfl_code = mfl_code;
Manuel Pégourié-Gonnard8b464592013-07-16 12:45:26 +02004835
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004836 return 0;
Manuel Pégourié-Gonnard8b464592013-07-16 12:45:26 +02004837}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004838#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
Manuel Pégourié-Gonnard8b464592013-07-16 12:45:26 +02004839
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004840#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004841void mbedtls_ssl_conf_truncated_hmac(mbedtls_ssl_config *conf, int truncate)
Manuel Pégourié-Gonnarde980a992013-07-19 11:08:52 +02004842{
Manuel Pégourié-Gonnardd36e33f2015-05-05 10:45:39 +02004843 conf->trunc_hmac = truncate;
Manuel Pégourié-Gonnarde980a992013-07-19 11:08:52 +02004844}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004845#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
Manuel Pégourié-Gonnarde980a992013-07-19 11:08:52 +02004846
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004847#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004848void mbedtls_ssl_conf_cbc_record_splitting(mbedtls_ssl_config *conf, char split)
Manuel Pégourié-Gonnardcfa477e2015-01-07 14:50:54 +01004849{
Manuel Pégourié-Gonnard17eab2b2015-05-05 16:34:53 +01004850 conf->cbc_record_splitting = split;
Manuel Pégourié-Gonnardcfa477e2015-01-07 14:50:54 +01004851}
4852#endif
4853
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004854void mbedtls_ssl_conf_legacy_renegotiation(mbedtls_ssl_config *conf, int allow_legacy)
Paul Bakker48916f92012-09-16 19:57:18 +00004855{
Manuel Pégourié-Gonnardd36e33f2015-05-05 10:45:39 +02004856 conf->allow_legacy_renegotiation = allow_legacy;
Paul Bakker48916f92012-09-16 19:57:18 +00004857}
4858
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004859#if defined(MBEDTLS_SSL_RENEGOTIATION)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004860void mbedtls_ssl_conf_renegotiation(mbedtls_ssl_config *conf, int renegotiation)
Manuel Pégourié-Gonnard615e6772014-11-03 08:23:14 +01004861{
Manuel Pégourié-Gonnardd36e33f2015-05-05 10:45:39 +02004862 conf->disable_renegotiation = renegotiation;
Manuel Pégourié-Gonnard615e6772014-11-03 08:23:14 +01004863}
4864
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004865void mbedtls_ssl_conf_renegotiation_enforced(mbedtls_ssl_config *conf, int max_records)
Manuel Pégourié-Gonnarda9964db2014-07-03 19:29:16 +02004866{
Manuel Pégourié-Gonnardd36e33f2015-05-05 10:45:39 +02004867 conf->renego_max_records = max_records;
Manuel Pégourié-Gonnarda9964db2014-07-03 19:29:16 +02004868}
4869
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004870void mbedtls_ssl_conf_renegotiation_period(mbedtls_ssl_config *conf,
4871 const unsigned char period[8])
Manuel Pégourié-Gonnard837f0fe2014-11-05 13:58:53 +01004872{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004873 memcpy(conf->renego_period, period, 8);
Manuel Pégourié-Gonnard837f0fe2014-11-05 13:58:53 +01004874}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004875#endif /* MBEDTLS_SSL_RENEGOTIATION */
Paul Bakker5121ce52009-01-03 21:22:43 +00004876
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004877#if defined(MBEDTLS_SSL_SESSION_TICKETS)
Manuel Pégourié-Gonnardb596abf2015-05-20 10:45:29 +02004878#if defined(MBEDTLS_SSL_CLI_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004879void mbedtls_ssl_conf_session_tickets(mbedtls_ssl_config *conf, int use_tickets)
Manuel Pégourié-Gonnardaa0d4d12013-08-03 13:02:31 +02004880{
Manuel Pégourié-Gonnard2b494452015-05-06 10:05:11 +01004881 conf->session_tickets = use_tickets;
Manuel Pégourié-Gonnardaa0d4d12013-08-03 13:02:31 +02004882}
Manuel Pégourié-Gonnardb596abf2015-05-20 10:45:29 +02004883#endif
Paul Bakker606b4ba2013-08-14 16:52:14 +02004884
Manuel Pégourié-Gonnardb596abf2015-05-20 10:45:29 +02004885#if defined(MBEDTLS_SSL_SRV_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004886void mbedtls_ssl_conf_session_tickets_cb(mbedtls_ssl_config *conf,
4887 mbedtls_ssl_ticket_write_t *f_ticket_write,
4888 mbedtls_ssl_ticket_parse_t *f_ticket_parse,
4889 void *p_ticket)
Paul Bakker606b4ba2013-08-14 16:52:14 +02004890{
Manuel Pégourié-Gonnardd59675d2015-05-19 15:28:00 +02004891 conf->f_ticket_write = f_ticket_write;
4892 conf->f_ticket_parse = f_ticket_parse;
4893 conf->p_ticket = p_ticket;
Paul Bakker606b4ba2013-08-14 16:52:14 +02004894}
Manuel Pégourié-Gonnardb596abf2015-05-20 10:45:29 +02004895#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004896#endif /* MBEDTLS_SSL_SESSION_TICKETS */
Manuel Pégourié-Gonnardaa0d4d12013-08-03 13:02:31 +02004897
Robert Cragie4feb7ae2015-10-02 13:33:37 +01004898#if defined(MBEDTLS_SSL_EXPORT_KEYS)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004899void mbedtls_ssl_conf_export_keys_cb(mbedtls_ssl_config *conf,
4900 mbedtls_ssl_export_keys_t *f_export_keys,
4901 void *p_export_keys)
Robert Cragie4feb7ae2015-10-02 13:33:37 +01004902{
4903 conf->f_export_keys = f_export_keys;
4904 conf->p_export_keys = p_export_keys;
4905}
Ron Eldorf5cc10d2019-05-07 18:33:40 +03004906
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004907void mbedtls_ssl_conf_export_keys_ext_cb(mbedtls_ssl_config *conf,
4908 mbedtls_ssl_export_keys_ext_t *f_export_keys_ext,
4909 void *p_export_keys)
Ron Eldorf5cc10d2019-05-07 18:33:40 +03004910{
4911 conf->f_export_keys_ext = f_export_keys_ext;
4912 conf->p_export_keys = p_export_keys;
4913}
Robert Cragie4feb7ae2015-10-02 13:33:37 +01004914#endif
4915
Gilles Peskineb74a1c72018-04-24 13:09:22 +02004916#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
Gilles Peskine8bf79f62018-01-05 21:11:53 +01004917void mbedtls_ssl_conf_async_private_cb(
4918 mbedtls_ssl_config *conf,
4919 mbedtls_ssl_async_sign_t *f_async_sign,
4920 mbedtls_ssl_async_decrypt_t *f_async_decrypt,
4921 mbedtls_ssl_async_resume_t *f_async_resume,
4922 mbedtls_ssl_async_cancel_t *f_async_cancel,
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004923 void *async_config_data)
Gilles Peskine8bf79f62018-01-05 21:11:53 +01004924{
4925 conf->f_async_sign_start = f_async_sign;
4926 conf->f_async_decrypt_start = f_async_decrypt;
4927 conf->f_async_resume = f_async_resume;
4928 conf->f_async_cancel = f_async_cancel;
Gilles Peskinedf13d5c2018-04-25 20:39:48 +02004929 conf->p_async_config_data = async_config_data;
4930}
4931
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004932void *mbedtls_ssl_conf_get_async_config_data(const mbedtls_ssl_config *conf)
Gilles Peskine8f97af72018-04-26 11:46:10 +02004933{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004934 return conf->p_async_config_data;
Gilles Peskine8f97af72018-04-26 11:46:10 +02004935}
4936
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004937void *mbedtls_ssl_get_async_operation_data(const mbedtls_ssl_context *ssl)
Gilles Peskinedf13d5c2018-04-25 20:39:48 +02004938{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004939 if (ssl->handshake == NULL) {
4940 return NULL;
4941 } else {
4942 return ssl->handshake->user_async_ctx;
4943 }
Gilles Peskinedf13d5c2018-04-25 20:39:48 +02004944}
4945
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004946void mbedtls_ssl_set_async_operation_data(mbedtls_ssl_context *ssl,
4947 void *ctx)
Gilles Peskinedf13d5c2018-04-25 20:39:48 +02004948{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004949 if (ssl->handshake != NULL) {
Gilles Peskinedf13d5c2018-04-25 20:39:48 +02004950 ssl->handshake->user_async_ctx = ctx;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004951 }
Gilles Peskine8bf79f62018-01-05 21:11:53 +01004952}
Gilles Peskineb74a1c72018-04-24 13:09:22 +02004953#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
Gilles Peskine8bf79f62018-01-05 21:11:53 +01004954
Paul Bakker5121ce52009-01-03 21:22:43 +00004955/*
4956 * SSL get accessors
4957 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004958uint32_t mbedtls_ssl_get_verify_result(const mbedtls_ssl_context *ssl)
Paul Bakker5121ce52009-01-03 21:22:43 +00004959{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004960 if (ssl->session != NULL) {
4961 return ssl->session->verify_result;
4962 }
Manuel Pégourié-Gonnarde89163c2015-01-23 14:30:57 +00004963
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004964 if (ssl->session_negotiate != NULL) {
4965 return ssl->session_negotiate->verify_result;
4966 }
Manuel Pégourié-Gonnarde89163c2015-01-23 14:30:57 +00004967
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004968 return 0xFFFFFFFF;
Paul Bakker5121ce52009-01-03 21:22:43 +00004969}
4970
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004971const char *mbedtls_ssl_get_ciphersuite(const mbedtls_ssl_context *ssl)
Paul Bakker72f62662011-01-16 21:27:44 +00004972{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004973 if (ssl == NULL || ssl->session == NULL) {
4974 return NULL;
4975 }
Paul Bakker926c8e42013-03-06 10:23:34 +01004976
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004977 return mbedtls_ssl_get_ciphersuite_name(ssl->session->ciphersuite);
Paul Bakker72f62662011-01-16 21:27:44 +00004978}
4979
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004980const char *mbedtls_ssl_get_version(const mbedtls_ssl_context *ssl)
Paul Bakker43ca69c2011-01-15 17:35:19 +00004981{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004982#if defined(MBEDTLS_SSL_PROTO_DTLS)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004983 if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
4984 switch (ssl->minor_ver) {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004985 case MBEDTLS_SSL_MINOR_VERSION_2:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004986 return "DTLSv1.0";
Manuel Pégourié-Gonnardb21ca2a2014-02-10 13:43:33 +01004987
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004988 case MBEDTLS_SSL_MINOR_VERSION_3:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004989 return "DTLSv1.2";
Manuel Pégourié-Gonnardb21ca2a2014-02-10 13:43:33 +01004990
4991 default:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004992 return "unknown (DTLS)";
Manuel Pégourié-Gonnardb21ca2a2014-02-10 13:43:33 +01004993 }
4994 }
4995#endif
4996
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004997 switch (ssl->minor_ver) {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004998 case MBEDTLS_SSL_MINOR_VERSION_0:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01004999 return "SSLv3.0";
Paul Bakker43ca69c2011-01-15 17:35:19 +00005000
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005001 case MBEDTLS_SSL_MINOR_VERSION_1:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005002 return "TLSv1.0";
Paul Bakker43ca69c2011-01-15 17:35:19 +00005003
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005004 case MBEDTLS_SSL_MINOR_VERSION_2:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005005 return "TLSv1.1";
Paul Bakker43ca69c2011-01-15 17:35:19 +00005006
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005007 case MBEDTLS_SSL_MINOR_VERSION_3:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005008 return "TLSv1.2";
Paul Bakker1ef83d62012-04-11 12:09:53 +00005009
Paul Bakker43ca69c2011-01-15 17:35:19 +00005010 default:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005011 return "unknown";
Paul Bakker43ca69c2011-01-15 17:35:19 +00005012 }
Paul Bakker43ca69c2011-01-15 17:35:19 +00005013}
5014
Manuel Pégourié-Gonnarda2cda6b2015-08-31 18:30:52 +02005015#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005016size_t mbedtls_ssl_get_input_max_frag_len(const mbedtls_ssl_context *ssl)
Andrzej Kurek90c6e842020-04-03 05:25:29 -04005017{
5018 size_t max_len = MBEDTLS_SSL_MAX_CONTENT_LEN;
5019 size_t read_mfl;
5020
5021 /* Use the configured MFL for the client if we're past SERVER_HELLO_DONE */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005022 if (ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT &&
5023 ssl->state >= MBEDTLS_SSL_SERVER_HELLO_DONE) {
5024 return ssl_mfl_code_to_length(ssl->conf->mfl_code);
Andrzej Kurek90c6e842020-04-03 05:25:29 -04005025 }
5026
5027 /* Check if a smaller max length was negotiated */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005028 if (ssl->session_out != NULL) {
5029 read_mfl = ssl_mfl_code_to_length(ssl->session_out->mfl_code);
5030 if (read_mfl < max_len) {
Andrzej Kurek90c6e842020-04-03 05:25:29 -04005031 max_len = read_mfl;
5032 }
5033 }
5034
5035 // During a handshake, use the value being negotiated
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005036 if (ssl->session_negotiate != NULL) {
5037 read_mfl = ssl_mfl_code_to_length(ssl->session_negotiate->mfl_code);
5038 if (read_mfl < max_len) {
Andrzej Kurek90c6e842020-04-03 05:25:29 -04005039 max_len = read_mfl;
5040 }
5041 }
5042
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005043 return max_len;
Andrzej Kurek90c6e842020-04-03 05:25:29 -04005044}
5045
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005046size_t mbedtls_ssl_get_output_max_frag_len(const mbedtls_ssl_context *ssl)
Manuel Pégourié-Gonnarda2cda6b2015-08-31 18:30:52 +02005047{
5048 size_t max_len;
5049
5050 /*
5051 * Assume mfl_code is correct since it was checked when set
5052 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005053 max_len = ssl_mfl_code_to_length(ssl->conf->mfl_code);
Manuel Pégourié-Gonnarda2cda6b2015-08-31 18:30:52 +02005054
Manuel Pégourié-Gonnard2cb17e22017-09-19 13:00:47 +02005055 /* Check if a smaller max length was negotiated */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005056 if (ssl->session_out != NULL &&
5057 ssl_mfl_code_to_length(ssl->session_out->mfl_code) < max_len) {
5058 max_len = ssl_mfl_code_to_length(ssl->session_out->mfl_code);
Manuel Pégourié-Gonnarda2cda6b2015-08-31 18:30:52 +02005059 }
5060
Manuel Pégourié-Gonnard2cb17e22017-09-19 13:00:47 +02005061 /* During a handshake, use the value being negotiated */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005062 if (ssl->session_negotiate != NULL &&
5063 ssl_mfl_code_to_length(ssl->session_negotiate->mfl_code) < max_len) {
5064 max_len = ssl_mfl_code_to_length(ssl->session_negotiate->mfl_code);
Manuel Pégourié-Gonnard2cb17e22017-09-19 13:00:47 +02005065 }
5066
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005067 return max_len;
Manuel Pégourié-Gonnarda2cda6b2015-08-31 18:30:52 +02005068}
Andrzej Kurek90c6e842020-04-03 05:25:29 -04005069
5070#if !defined(MBEDTLS_DEPRECATED_REMOVED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005071size_t mbedtls_ssl_get_max_frag_len(const mbedtls_ssl_context *ssl)
Andrzej Kurek90c6e842020-04-03 05:25:29 -04005072{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005073 return mbedtls_ssl_get_output_max_frag_len(ssl);
Andrzej Kurek90c6e842020-04-03 05:25:29 -04005074}
5075#endif /* !MBEDTLS_DEPRECATED_REMOVED */
Manuel Pégourié-Gonnarda2cda6b2015-08-31 18:30:52 +02005076#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
5077
Manuel Pégourié-Gonnardb8eec192018-08-20 09:34:02 +02005078#if defined(MBEDTLS_SSL_PROTO_DTLS)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005079size_t mbedtls_ssl_get_current_mtu(const mbedtls_ssl_context *ssl)
Manuel Pégourié-Gonnardb8eec192018-08-20 09:34:02 +02005080{
Andrzej Kurekef43ce62018-10-09 08:24:12 -04005081 /* Return unlimited mtu for client hello messages to avoid fragmentation. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005082 if (ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT &&
5083 (ssl->state == MBEDTLS_SSL_CLIENT_HELLO ||
5084 ssl->state == MBEDTLS_SSL_SERVER_HELLO)) {
5085 return 0;
5086 }
Andrzej Kurekef43ce62018-10-09 08:24:12 -04005087
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005088 if (ssl->handshake == NULL || ssl->handshake->mtu == 0) {
5089 return ssl->mtu;
5090 }
Manuel Pégourié-Gonnardb8eec192018-08-20 09:34:02 +02005091
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005092 if (ssl->mtu == 0) {
5093 return ssl->handshake->mtu;
5094 }
Manuel Pégourié-Gonnardb8eec192018-08-20 09:34:02 +02005095
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005096 return ssl->mtu < ssl->handshake->mtu ?
5097 ssl->mtu : ssl->handshake->mtu;
Manuel Pégourié-Gonnardb8eec192018-08-20 09:34:02 +02005098}
5099#endif /* MBEDTLS_SSL_PROTO_DTLS */
5100
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005101int mbedtls_ssl_get_max_out_record_payload(const mbedtls_ssl_context *ssl)
Manuel Pégourié-Gonnard9468ff12017-09-21 13:49:50 +02005102{
5103 size_t max_len = MBEDTLS_SSL_OUT_CONTENT_LEN;
5104
Manuel Pégourié-Gonnard000281e2018-08-21 11:20:58 +02005105#if !defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) && \
5106 !defined(MBEDTLS_SSL_PROTO_DTLS)
5107 (void) ssl;
5108#endif
5109
Manuel Pégourié-Gonnard9468ff12017-09-21 13:49:50 +02005110#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005111 const size_t mfl = mbedtls_ssl_get_output_max_frag_len(ssl);
Manuel Pégourié-Gonnard9468ff12017-09-21 13:49:50 +02005112
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005113 if (max_len > mfl) {
Manuel Pégourié-Gonnard9468ff12017-09-21 13:49:50 +02005114 max_len = mfl;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005115 }
Manuel Pégourié-Gonnard9468ff12017-09-21 13:49:50 +02005116#endif
5117
5118#if defined(MBEDTLS_SSL_PROTO_DTLS)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005119 if (mbedtls_ssl_get_current_mtu(ssl) != 0) {
5120 const size_t mtu = mbedtls_ssl_get_current_mtu(ssl);
5121 const int ret = mbedtls_ssl_get_record_expansion(ssl);
Manuel Pégourié-Gonnard9468ff12017-09-21 13:49:50 +02005122 const size_t overhead = (size_t) ret;
5123
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005124 if (ret < 0) {
5125 return ret;
Manuel Pégourié-Gonnard9468ff12017-09-21 13:49:50 +02005126 }
5127
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005128 if (mtu <= overhead) {
5129 MBEDTLS_SSL_DEBUG_MSG(1, ("MTU too low for record expansion"));
5130 return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
5131 }
5132
5133 if (max_len > mtu - overhead) {
Manuel Pégourié-Gonnard9468ff12017-09-21 13:49:50 +02005134 max_len = mtu - overhead;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005135 }
Manuel Pégourié-Gonnard9468ff12017-09-21 13:49:50 +02005136 }
Manuel Pégourié-Gonnardb8eec192018-08-20 09:34:02 +02005137#endif /* MBEDTLS_SSL_PROTO_DTLS */
Manuel Pégourié-Gonnard9468ff12017-09-21 13:49:50 +02005138
Hanno Becker0defedb2018-08-10 12:35:02 +01005139#if !defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) && \
5140 !defined(MBEDTLS_SSL_PROTO_DTLS)
5141 ((void) ssl);
Manuel Pégourié-Gonnard9468ff12017-09-21 13:49:50 +02005142#endif
5143
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005144 return (int) max_len;
Manuel Pégourié-Gonnard9468ff12017-09-21 13:49:50 +02005145}
5146
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005147#if defined(MBEDTLS_X509_CRT_PARSE_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005148const mbedtls_x509_crt *mbedtls_ssl_get_peer_cert(const mbedtls_ssl_context *ssl)
Paul Bakkerb0550d92012-10-30 07:51:03 +00005149{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005150 if (ssl == NULL || ssl->session == NULL) {
5151 return NULL;
5152 }
Paul Bakkerb0550d92012-10-30 07:51:03 +00005153
Hanno Beckere6824572019-02-07 13:18:46 +00005154#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005155 return ssl->session->peer_cert;
Hanno Beckere6824572019-02-07 13:18:46 +00005156#else
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005157 return NULL;
Hanno Beckere6824572019-02-07 13:18:46 +00005158#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
Paul Bakkerb0550d92012-10-30 07:51:03 +00005159}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005160#endif /* MBEDTLS_X509_CRT_PARSE_C */
Paul Bakkerb0550d92012-10-30 07:51:03 +00005161
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005162#if defined(MBEDTLS_SSL_CLI_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005163int mbedtls_ssl_get_session(const mbedtls_ssl_context *ssl,
5164 mbedtls_ssl_session *dst)
Manuel Pégourié-Gonnard74718032013-07-30 12:41:56 +02005165{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005166 if (ssl == NULL ||
Manuel Pégourié-Gonnard74718032013-07-30 12:41:56 +02005167 dst == NULL ||
5168 ssl->session == NULL ||
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005169 ssl->conf->endpoint != MBEDTLS_SSL_IS_CLIENT) {
5170 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
Manuel Pégourié-Gonnard74718032013-07-30 12:41:56 +02005171 }
5172
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005173 return mbedtls_ssl_session_copy(dst, ssl->session);
Manuel Pégourié-Gonnard74718032013-07-30 12:41:56 +02005174}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005175#endif /* MBEDTLS_SSL_CLI_C */
Manuel Pégourié-Gonnard74718032013-07-30 12:41:56 +02005176
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005177const mbedtls_ssl_session *mbedtls_ssl_get_session_pointer(const mbedtls_ssl_context *ssl)
Manuel Pégourié-Gonnardb5e4e0a2019-05-20 11:12:28 +02005178{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005179 if (ssl == NULL) {
5180 return NULL;
5181 }
Manuel Pégourié-Gonnardb5e4e0a2019-05-20 11:12:28 +02005182
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005183 return ssl->session;
Manuel Pégourié-Gonnardb5e4e0a2019-05-20 11:12:28 +02005184}
5185
Paul Bakker5121ce52009-01-03 21:22:43 +00005186/*
Hanno Beckera835da52019-05-16 12:39:07 +01005187 * Define ticket header determining Mbed TLS version
5188 * and structure of the ticket.
5189 */
5190
Hanno Becker94ef3b32019-05-16 12:50:45 +01005191/*
Hanno Becker50b59662019-05-28 14:30:45 +01005192 * Define bitflag determining compile-time settings influencing
5193 * structure of serialized SSL sessions.
Hanno Becker94ef3b32019-05-16 12:50:45 +01005194 */
5195
Hanno Becker50b59662019-05-28 14:30:45 +01005196#if defined(MBEDTLS_HAVE_TIME)
Hanno Becker3e088662019-05-29 11:10:18 +01005197#define SSL_SERIALIZED_SESSION_CONFIG_TIME 1
Hanno Becker50b59662019-05-28 14:30:45 +01005198#else
Hanno Becker3e088662019-05-29 11:10:18 +01005199#define SSL_SERIALIZED_SESSION_CONFIG_TIME 0
Hanno Becker94ef3b32019-05-16 12:50:45 +01005200#endif /* MBEDTLS_HAVE_TIME */
5201
5202#if defined(MBEDTLS_X509_CRT_PARSE_C)
Hanno Becker3e088662019-05-29 11:10:18 +01005203#define SSL_SERIALIZED_SESSION_CONFIG_CRT 1
Hanno Becker94ef3b32019-05-16 12:50:45 +01005204#else
Hanno Becker3e088662019-05-29 11:10:18 +01005205#define SSL_SERIALIZED_SESSION_CONFIG_CRT 0
Hanno Becker94ef3b32019-05-16 12:50:45 +01005206#endif /* MBEDTLS_X509_CRT_PARSE_C */
5207
5208#if defined(MBEDTLS_SSL_CLI_C) && defined(MBEDTLS_SSL_SESSION_TICKETS)
Hanno Becker3e088662019-05-29 11:10:18 +01005209#define SSL_SERIALIZED_SESSION_CONFIG_CLIENT_TICKET 1
Hanno Becker94ef3b32019-05-16 12:50:45 +01005210#else
Hanno Becker3e088662019-05-29 11:10:18 +01005211#define SSL_SERIALIZED_SESSION_CONFIG_CLIENT_TICKET 0
Hanno Becker94ef3b32019-05-16 12:50:45 +01005212#endif /* MBEDTLS_SSL_CLI_C && MBEDTLS_SSL_SESSION_TICKETS */
5213
5214#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
Hanno Becker3e088662019-05-29 11:10:18 +01005215#define SSL_SERIALIZED_SESSION_CONFIG_MFL 1
Hanno Becker94ef3b32019-05-16 12:50:45 +01005216#else
Hanno Becker3e088662019-05-29 11:10:18 +01005217#define SSL_SERIALIZED_SESSION_CONFIG_MFL 0
Hanno Becker94ef3b32019-05-16 12:50:45 +01005218#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
5219
5220#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
Hanno Becker3e088662019-05-29 11:10:18 +01005221#define SSL_SERIALIZED_SESSION_CONFIG_TRUNC_HMAC 1
Hanno Becker94ef3b32019-05-16 12:50:45 +01005222#else
Hanno Becker3e088662019-05-29 11:10:18 +01005223#define SSL_SERIALIZED_SESSION_CONFIG_TRUNC_HMAC 0
Hanno Becker94ef3b32019-05-16 12:50:45 +01005224#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
5225
5226#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
Hanno Becker3e088662019-05-29 11:10:18 +01005227#define SSL_SERIALIZED_SESSION_CONFIG_ETM 1
Hanno Becker94ef3b32019-05-16 12:50:45 +01005228#else
Hanno Becker3e088662019-05-29 11:10:18 +01005229#define SSL_SERIALIZED_SESSION_CONFIG_ETM 0
Hanno Becker94ef3b32019-05-16 12:50:45 +01005230#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
5231
Hanno Becker94ef3b32019-05-16 12:50:45 +01005232#if defined(MBEDTLS_SSL_SESSION_TICKETS)
5233#define SSL_SERIALIZED_SESSION_CONFIG_TICKET 1
5234#else
5235#define SSL_SERIALIZED_SESSION_CONFIG_TICKET 0
5236#endif /* MBEDTLS_SSL_SESSION_TICKETS */
5237
Hanno Becker3e088662019-05-29 11:10:18 +01005238#define SSL_SERIALIZED_SESSION_CONFIG_TIME_BIT 0
5239#define SSL_SERIALIZED_SESSION_CONFIG_CRT_BIT 1
5240#define SSL_SERIALIZED_SESSION_CONFIG_CLIENT_TICKET_BIT 2
5241#define SSL_SERIALIZED_SESSION_CONFIG_MFL_BIT 3
5242#define SSL_SERIALIZED_SESSION_CONFIG_TRUNC_HMAC_BIT 4
5243#define SSL_SERIALIZED_SESSION_CONFIG_ETM_BIT 5
5244#define SSL_SERIALIZED_SESSION_CONFIG_TICKET_BIT 6
Hanno Becker3e088662019-05-29 11:10:18 +01005245
Hanno Becker50b59662019-05-28 14:30:45 +01005246#define SSL_SERIALIZED_SESSION_CONFIG_BITFLAG \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005247 ((uint16_t) ( \
5248 (SSL_SERIALIZED_SESSION_CONFIG_TIME << SSL_SERIALIZED_SESSION_CONFIG_TIME_BIT) | \
5249 (SSL_SERIALIZED_SESSION_CONFIG_CRT << SSL_SERIALIZED_SESSION_CONFIG_CRT_BIT) | \
5250 (SSL_SERIALIZED_SESSION_CONFIG_CLIENT_TICKET << \
5251 SSL_SERIALIZED_SESSION_CONFIG_CLIENT_TICKET_BIT) | \
5252 (SSL_SERIALIZED_SESSION_CONFIG_MFL << SSL_SERIALIZED_SESSION_CONFIG_MFL_BIT) | \
5253 (SSL_SERIALIZED_SESSION_CONFIG_TRUNC_HMAC << \
5254 SSL_SERIALIZED_SESSION_CONFIG_TRUNC_HMAC_BIT) | \
5255 (SSL_SERIALIZED_SESSION_CONFIG_ETM << SSL_SERIALIZED_SESSION_CONFIG_ETM_BIT) | \
5256 (SSL_SERIALIZED_SESSION_CONFIG_TICKET << SSL_SERIALIZED_SESSION_CONFIG_TICKET_BIT)))
Hanno Becker94ef3b32019-05-16 12:50:45 +01005257
Hanno Beckerf8787072019-05-16 12:41:07 +01005258static unsigned char ssl_serialized_session_header[] = {
Hanno Becker94ef3b32019-05-16 12:50:45 +01005259 MBEDTLS_VERSION_MAJOR,
5260 MBEDTLS_VERSION_MINOR,
5261 MBEDTLS_VERSION_PATCH,
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005262 MBEDTLS_BYTE_1(SSL_SERIALIZED_SESSION_CONFIG_BITFLAG),
5263 MBEDTLS_BYTE_0(SSL_SERIALIZED_SESSION_CONFIG_BITFLAG),
Hanno Beckerf8787072019-05-16 12:41:07 +01005264};
Hanno Beckera835da52019-05-16 12:39:07 +01005265
5266/*
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005267 * Serialize a session in the following format:
Manuel Pégourié-Gonnard35eb8022019-05-16 11:11:08 +02005268 * (in the presentation language of TLS, RFC 8446 section 3)
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005269 *
Hanno Becker50b59662019-05-28 14:30:45 +01005270 * opaque mbedtls_version[3]; // major, minor, patch
5271 * opaque session_format[2]; // version-specific 16-bit field determining
5272 * // the format of the remaining
5273 * // serialized data.
Hanno Beckerdc28b6c2019-05-29 11:08:00 +01005274 *
5275 * Note: When updating the format, remember to keep
5276 * these version+format bytes.
5277 *
Hanno Beckerbe34e8e2019-06-04 09:43:16 +01005278 * // In this version, `session_format` determines
5279 * // the setting of those compile-time
5280 * // configuration options which influence
Hanno Becker50b59662019-05-28 14:30:45 +01005281 * // the structure of mbedtls_ssl_session.
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005282 * uint64 start_time;
Hanno Becker50b59662019-05-28 14:30:45 +01005283 * uint8 ciphersuite[2]; // defined by the standard
5284 * uint8 compression; // 0 or 1
5285 * uint8 session_id_len; // at most 32
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005286 * opaque session_id[32];
Hanno Becker50b59662019-05-28 14:30:45 +01005287 * opaque master[48]; // fixed length in the standard
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005288 * uint32 verify_result;
Hanno Becker50b59662019-05-28 14:30:45 +01005289 * opaque peer_cert<0..2^24-1>; // length 0 means no peer cert
5290 * opaque ticket<0..2^24-1>; // length 0 means no ticket
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005291 * uint32 ticket_lifetime;
Hanno Becker50b59662019-05-28 14:30:45 +01005292 * uint8 mfl_code; // up to 255 according to standard
5293 * uint8 trunc_hmac; // 0 or 1
5294 * uint8 encrypt_then_mac; // 0 or 1
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005295 *
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005296 * The order is the same as in the definition of the structure, except
5297 * verify_result is put before peer_cert so that all mandatory fields come
5298 * together in one block.
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005299 */
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +02005300MBEDTLS_CHECK_RETURN_CRITICAL
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005301static int ssl_session_save(const mbedtls_ssl_session *session,
5302 unsigned char omit_header,
5303 unsigned char *buf,
5304 size_t buf_len,
5305 size_t *olen)
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005306{
5307 unsigned char *p = buf;
Manuel Pégourié-Gonnard26f982f2019-05-21 11:01:32 +02005308 size_t used = 0;
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005309#if defined(MBEDTLS_HAVE_TIME)
5310 uint64_t start;
5311#endif
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005312#if defined(MBEDTLS_X509_CRT_PARSE_C)
5313#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
5314 size_t cert_len;
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005315#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
5316#endif /* MBEDTLS_X509_CRT_PARSE_C */
5317
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005318
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005319 if (!omit_header) {
Manuel Pégourié-Gonnard45ac1f02019-07-23 16:52:45 +02005320 /*
5321 * Add version identifier
5322 */
5323
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005324 used += sizeof(ssl_serialized_session_header);
Manuel Pégourié-Gonnard45ac1f02019-07-23 16:52:45 +02005325
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005326 if (used <= buf_len) {
5327 memcpy(p, ssl_serialized_session_header,
5328 sizeof(ssl_serialized_session_header));
5329 p += sizeof(ssl_serialized_session_header);
Manuel Pégourié-Gonnard45ac1f02019-07-23 16:52:45 +02005330 }
Hanno Beckera835da52019-05-16 12:39:07 +01005331 }
5332
5333 /*
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005334 * Time
5335 */
5336#if defined(MBEDTLS_HAVE_TIME)
5337 used += 8;
5338
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005339 if (used <= buf_len) {
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005340 start = (uint64_t) session->start;
5341
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005342 MBEDTLS_PUT_UINT64_BE(start, p, 0);
Joe Subbiani2f98d792021-08-20 11:44:44 +01005343 p += 8;
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005344 }
5345#endif /* MBEDTLS_HAVE_TIME */
5346
5347 /*
5348 * Basic mandatory fields
5349 */
5350 used += 2 /* ciphersuite */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005351 + 1 /* compression */
5352 + 1 /* id_len */
5353 + sizeof(session->id)
5354 + sizeof(session->master)
5355 + 4; /* verify_result */
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005356
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005357 if (used <= buf_len) {
5358 MBEDTLS_PUT_UINT16_BE(session->ciphersuite, p, 0);
Joe Subbiani2f98d792021-08-20 11:44:44 +01005359 p += 2;
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005360
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005361 *p++ = MBEDTLS_BYTE_0(session->compression);
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005362
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005363 *p++ = MBEDTLS_BYTE_0(session->id_len);
5364 memcpy(p, session->id, 32);
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005365 p += 32;
5366
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005367 memcpy(p, session->master, 48);
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005368 p += 48;
5369
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005370 MBEDTLS_PUT_UINT32_BE(session->verify_result, p, 0);
Joe Subbiani2f98d792021-08-20 11:44:44 +01005371 p += 4;
Manuel Pégourié-Gonnard26f982f2019-05-21 11:01:32 +02005372 }
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005373
Manuel Pégourié-Gonnard35eb8022019-05-16 11:11:08 +02005374 /*
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005375 * Peer's end-entity certificate
Manuel Pégourié-Gonnard35eb8022019-05-16 11:11:08 +02005376 */
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005377#if defined(MBEDTLS_X509_CRT_PARSE_C)
5378#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005379 if (session->peer_cert == NULL) {
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005380 cert_len = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005381 } else {
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005382 cert_len = session->peer_cert->raw.len;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005383 }
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005384
Manuel Pégourié-Gonnard26f982f2019-05-21 11:01:32 +02005385 used += 3 + cert_len;
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005386
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005387 if (used <= buf_len) {
5388 *p++ = MBEDTLS_BYTE_2(cert_len);
5389 *p++ = MBEDTLS_BYTE_1(cert_len);
5390 *p++ = MBEDTLS_BYTE_0(cert_len);
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005391
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005392 if (session->peer_cert != NULL) {
5393 memcpy(p, session->peer_cert->raw.p, cert_len);
Manuel Pégourié-Gonnard26f982f2019-05-21 11:01:32 +02005394 p += cert_len;
5395 }
5396 }
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005397#else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005398 if (session->peer_cert_digest != NULL) {
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005399 used += 1 /* type */ + 1 /* length */ + session->peer_cert_digest_len;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005400 if (used <= buf_len) {
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005401 *p++ = (unsigned char) session->peer_cert_digest_type;
5402 *p++ = (unsigned char) session->peer_cert_digest_len;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005403 memcpy(p, session->peer_cert_digest,
5404 session->peer_cert_digest_len);
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005405 p += session->peer_cert_digest_len;
5406 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005407 } else {
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005408 used += 2;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005409 if (used <= buf_len) {
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005410 *p++ = (unsigned char) MBEDTLS_MD_NONE;
5411 *p++ = 0;
5412 }
Manuel Pégourié-Gonnard26f982f2019-05-21 11:01:32 +02005413 }
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005414#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
5415#endif /* MBEDTLS_X509_CRT_PARSE_C */
5416
Manuel Pégourié-Gonnard35eb8022019-05-16 11:11:08 +02005417 /*
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005418 * Session ticket if any, plus associated data
Manuel Pégourié-Gonnard35eb8022019-05-16 11:11:08 +02005419 */
5420#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005421 used += 3 + session->ticket_len + 4; /* len + ticket + lifetime */
Manuel Pégourié-Gonnard35eb8022019-05-16 11:11:08 +02005422
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005423 if (used <= buf_len) {
5424 *p++ = MBEDTLS_BYTE_2(session->ticket_len);
5425 *p++ = MBEDTLS_BYTE_1(session->ticket_len);
5426 *p++ = MBEDTLS_BYTE_0(session->ticket_len);
Manuel Pégourié-Gonnard26f982f2019-05-21 11:01:32 +02005427
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005428 if (session->ticket != NULL) {
5429 memcpy(p, session->ticket, session->ticket_len);
Manuel Pégourié-Gonnard26f982f2019-05-21 11:01:32 +02005430 p += session->ticket_len;
5431 }
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005432
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005433 MBEDTLS_PUT_UINT32_BE(session->ticket_lifetime, p, 0);
Joe Subbiani2f98d792021-08-20 11:44:44 +01005434 p += 4;
Manuel Pégourié-Gonnard35eb8022019-05-16 11:11:08 +02005435 }
5436#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */
5437
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005438 /*
5439 * Misc extension-related info
5440 */
5441#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
5442 used += 1;
5443
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005444 if (used <= buf_len) {
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005445 *p++ = session->mfl_code;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005446 }
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005447#endif
5448
5449#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
5450 used += 1;
5451
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005452 if (used <= buf_len) {
5453 *p++ = (unsigned char) ((session->trunc_hmac) & 0xFF);
5454 }
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005455#endif
5456
5457#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
5458 used += 1;
5459
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005460 if (used <= buf_len) {
5461 *p++ = MBEDTLS_BYTE_0(session->encrypt_then_mac);
5462 }
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005463#endif
5464
Manuel Pégourié-Gonnard35eb8022019-05-16 11:11:08 +02005465 /* Done */
Manuel Pégourié-Gonnard26f982f2019-05-21 11:01:32 +02005466 *olen = used;
5467
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005468 if (used > buf_len) {
5469 return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL;
5470 }
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005471
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005472 return 0;
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005473}
5474
5475/*
Manuel Pégourié-Gonnard45ac1f02019-07-23 16:52:45 +02005476 * Public wrapper for ssl_session_save()
5477 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005478int mbedtls_ssl_session_save(const mbedtls_ssl_session *session,
5479 unsigned char *buf,
5480 size_t buf_len,
5481 size_t *olen)
Manuel Pégourié-Gonnard45ac1f02019-07-23 16:52:45 +02005482{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005483 return ssl_session_save(session, 0, buf, buf_len, olen);
Manuel Pégourié-Gonnard45ac1f02019-07-23 16:52:45 +02005484}
5485
5486/*
Manuel Pégourié-Gonnardb9dfc9f2019-07-12 10:50:19 +02005487 * Deserialize session, see mbedtls_ssl_session_save() for format.
Manuel Pégourié-Gonnarda3d831b2019-05-23 12:28:45 +02005488 *
5489 * This internal version is wrapped by a public function that cleans up in
Manuel Pégourié-Gonnard45ac1f02019-07-23 16:52:45 +02005490 * case of error, and has an extra option omit_header.
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005491 */
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +02005492MBEDTLS_CHECK_RETURN_CRITICAL
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005493static int ssl_session_load(mbedtls_ssl_session *session,
5494 unsigned char omit_header,
5495 const unsigned char *buf,
5496 size_t len)
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005497{
5498 const unsigned char *p = buf;
5499 const unsigned char * const end = buf + len;
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005500#if defined(MBEDTLS_HAVE_TIME)
5501 uint64_t start;
5502#endif
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005503#if defined(MBEDTLS_X509_CRT_PARSE_C)
5504#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
5505 size_t cert_len;
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005506#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
5507#endif /* MBEDTLS_X509_CRT_PARSE_C */
5508
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005509 if (!omit_header) {
Manuel Pégourié-Gonnard45ac1f02019-07-23 16:52:45 +02005510 /*
5511 * Check version identifier
5512 */
5513
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005514 if ((size_t) (end - p) < sizeof(ssl_serialized_session_header)) {
5515 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
Manuel Pégourié-Gonnard45ac1f02019-07-23 16:52:45 +02005516 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005517
5518 if (memcmp(p, ssl_serialized_session_header,
5519 sizeof(ssl_serialized_session_header)) != 0) {
5520 return MBEDTLS_ERR_SSL_VERSION_MISMATCH;
5521 }
5522 p += sizeof(ssl_serialized_session_header);
Hanno Beckera835da52019-05-16 12:39:07 +01005523 }
Hanno Beckera835da52019-05-16 12:39:07 +01005524
5525 /*
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005526 * Time
Manuel Pégourié-Gonnard35eb8022019-05-16 11:11:08 +02005527 */
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005528#if defined(MBEDTLS_HAVE_TIME)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005529 if (8 > (size_t) (end - p)) {
5530 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
5531 }
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005532
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005533 start = ((uint64_t) p[0] << 56) |
5534 ((uint64_t) p[1] << 48) |
5535 ((uint64_t) p[2] << 40) |
5536 ((uint64_t) p[3] << 32) |
5537 ((uint64_t) p[4] << 24) |
5538 ((uint64_t) p[5] << 16) |
5539 ((uint64_t) p[6] << 8) |
5540 ((uint64_t) p[7]);
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005541 p += 8;
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005542
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005543 session->start = (time_t) start;
5544#endif /* MBEDTLS_HAVE_TIME */
5545
5546 /*
5547 * Basic mandatory fields
5548 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005549 if (2 + 1 + 1 + 32 + 48 + 4 > (size_t) (end - p)) {
5550 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
5551 }
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005552
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005553 session->ciphersuite = (p[0] << 8) | p[1];
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005554 p += 2;
5555
5556 session->compression = *p++;
5557
5558 session->id_len = *p++;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005559 memcpy(session->id, p, 32);
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005560 p += 32;
5561
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005562 memcpy(session->master, p, 48);
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005563 p += 48;
5564
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005565 session->verify_result = ((uint32_t) p[0] << 24) |
5566 ((uint32_t) p[1] << 16) |
5567 ((uint32_t) p[2] << 8) |
5568 ((uint32_t) p[3]);
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005569 p += 4;
5570
5571 /* Immediately clear invalid pointer values that have been read, in case
5572 * we exit early before we replaced them with valid ones. */
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005573#if defined(MBEDTLS_X509_CRT_PARSE_C)
5574#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
5575 session->peer_cert = NULL;
5576#else
5577 session->peer_cert_digest = NULL;
5578#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
5579#endif /* MBEDTLS_X509_CRT_PARSE_C */
5580#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
5581 session->ticket = NULL;
5582#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */
5583
Manuel Pégourié-Gonnard35eb8022019-05-16 11:11:08 +02005584 /*
5585 * Peer certificate
5586 */
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005587#if defined(MBEDTLS_X509_CRT_PARSE_C)
5588#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
5589 /* Deserialize CRT from the end of the ticket. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005590 if (3 > (size_t) (end - p)) {
5591 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
5592 }
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005593
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005594 cert_len = (p[0] << 16) | (p[1] << 8) | p[2];
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005595 p += 3;
5596
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005597 if (cert_len != 0) {
Janos Follath865b3eb2019-12-16 11:46:15 +00005598 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005599
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005600 if (cert_len > (size_t) (end - p)) {
5601 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
5602 }
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005603
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005604 session->peer_cert = mbedtls_calloc(1, sizeof(mbedtls_x509_crt));
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005605
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005606 if (session->peer_cert == NULL) {
5607 return MBEDTLS_ERR_SSL_ALLOC_FAILED;
5608 }
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005609
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005610 mbedtls_x509_crt_init(session->peer_cert);
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005611
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005612 if ((ret = mbedtls_x509_crt_parse_der(session->peer_cert,
5613 p, cert_len)) != 0) {
5614 mbedtls_x509_crt_free(session->peer_cert);
5615 mbedtls_free(session->peer_cert);
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005616 session->peer_cert = NULL;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005617 return ret;
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005618 }
5619
5620 p += cert_len;
5621 }
5622#else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
5623 /* Deserialize CRT digest from the end of the ticket. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005624 if (2 > (size_t) (end - p)) {
5625 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
5626 }
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005627
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005628 session->peer_cert_digest_type = (mbedtls_md_type_t) *p++;
5629 session->peer_cert_digest_len = (size_t) *p++;
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005630
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005631 if (session->peer_cert_digest_len != 0) {
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005632 const mbedtls_md_info_t *md_info =
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005633 mbedtls_md_info_from_type(session->peer_cert_digest_type);
5634 if (md_info == NULL) {
5635 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
5636 }
5637 if (session->peer_cert_digest_len != mbedtls_md_get_size(md_info)) {
5638 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
5639 }
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005640
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005641 if (session->peer_cert_digest_len > (size_t) (end - p)) {
5642 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
5643 }
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005644
5645 session->peer_cert_digest =
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005646 mbedtls_calloc(1, session->peer_cert_digest_len);
5647 if (session->peer_cert_digest == NULL) {
5648 return MBEDTLS_ERR_SSL_ALLOC_FAILED;
5649 }
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005650
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005651 memcpy(session->peer_cert_digest, p,
5652 session->peer_cert_digest_len);
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005653 p += session->peer_cert_digest_len;
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005654 }
5655#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
5656#endif /* MBEDTLS_X509_CRT_PARSE_C */
5657
Manuel Pégourié-Gonnard35eb8022019-05-16 11:11:08 +02005658 /*
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005659 * Session ticket and associated data
Manuel Pégourié-Gonnard35eb8022019-05-16 11:11:08 +02005660 */
5661#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005662 if (3 > (size_t) (end - p)) {
5663 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
5664 }
Manuel Pégourié-Gonnard35eb8022019-05-16 11:11:08 +02005665
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005666 session->ticket_len = (p[0] << 16) | (p[1] << 8) | p[2];
Manuel Pégourié-Gonnard35eb8022019-05-16 11:11:08 +02005667 p += 3;
5668
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005669 if (session->ticket_len != 0) {
5670 if (session->ticket_len > (size_t) (end - p)) {
5671 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
5672 }
Manuel Pégourié-Gonnard35eb8022019-05-16 11:11:08 +02005673
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005674 session->ticket = mbedtls_calloc(1, session->ticket_len);
5675 if (session->ticket == NULL) {
5676 return MBEDTLS_ERR_SSL_ALLOC_FAILED;
5677 }
Manuel Pégourié-Gonnard35eb8022019-05-16 11:11:08 +02005678
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005679 memcpy(session->ticket, p, session->ticket_len);
Manuel Pégourié-Gonnard35eb8022019-05-16 11:11:08 +02005680 p += session->ticket_len;
5681 }
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005682
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005683 if (4 > (size_t) (end - p)) {
5684 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
5685 }
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005686
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005687 session->ticket_lifetime = ((uint32_t) p[0] << 24) |
5688 ((uint32_t) p[1] << 16) |
5689 ((uint32_t) p[2] << 8) |
5690 ((uint32_t) p[3]);
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005691 p += 4;
Manuel Pégourié-Gonnard35eb8022019-05-16 11:11:08 +02005692#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */
5693
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005694 /*
5695 * Misc extension-related info
5696 */
5697#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005698 if (1 > (size_t) (end - p)) {
5699 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
5700 }
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005701
5702 session->mfl_code = *p++;
5703#endif
5704
5705#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005706 if (1 > (size_t) (end - p)) {
5707 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
5708 }
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005709
5710 session->trunc_hmac = *p++;
5711#endif
5712
5713#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005714 if (1 > (size_t) (end - p)) {
5715 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
5716 }
Manuel Pégourié-Gonnardf743c032019-05-24 12:06:29 +02005717
5718 session->encrypt_then_mac = *p++;
5719#endif
5720
Manuel Pégourié-Gonnard35eb8022019-05-16 11:11:08 +02005721 /* Done, should have consumed entire buffer */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005722 if (p != end) {
5723 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
5724 }
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005725
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005726 return 0;
Manuel Pégourié-Gonnarda3e7c652019-05-16 10:08:35 +02005727}
5728
5729/*
Manuel Pégourié-Gonnardb9dfc9f2019-07-12 10:50:19 +02005730 * Deserialize session: public wrapper for error cleaning
Manuel Pégourié-Gonnarda3d831b2019-05-23 12:28:45 +02005731 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005732int mbedtls_ssl_session_load(mbedtls_ssl_session *session,
5733 const unsigned char *buf,
5734 size_t len)
Manuel Pégourié-Gonnarda3d831b2019-05-23 12:28:45 +02005735{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005736 int ret = ssl_session_load(session, 0, buf, len);
Manuel Pégourié-Gonnarda3d831b2019-05-23 12:28:45 +02005737
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005738 if (ret != 0) {
5739 mbedtls_ssl_session_free(session);
5740 }
Manuel Pégourié-Gonnarda3d831b2019-05-23 12:28:45 +02005741
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005742 return ret;
Manuel Pégourié-Gonnarda3d831b2019-05-23 12:28:45 +02005743}
5744
5745/*
Paul Bakker1961b702013-01-25 14:49:24 +01005746 * Perform a single step of the SSL handshake
Paul Bakker5121ce52009-01-03 21:22:43 +00005747 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005748int mbedtls_ssl_handshake_step(mbedtls_ssl_context *ssl)
Paul Bakker5121ce52009-01-03 21:22:43 +00005749{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005750 int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
Paul Bakker5121ce52009-01-03 21:22:43 +00005751
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005752 if (ssl == NULL || ssl->conf == NULL) {
5753 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
5754 }
Manuel Pégourié-Gonnardf81ee2e2015-09-01 17:43:40 +02005755
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005756#if defined(MBEDTLS_SSL_CLI_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005757 if (ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT) {
5758 ret = mbedtls_ssl_handshake_client_step(ssl);
5759 }
Paul Bakker5121ce52009-01-03 21:22:43 +00005760#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005761#if defined(MBEDTLS_SSL_SRV_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005762 if (ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER) {
5763 ret = mbedtls_ssl_handshake_server_step(ssl);
5764 }
Paul Bakker5121ce52009-01-03 21:22:43 +00005765#endif
5766
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005767 return ret;
Paul Bakker1961b702013-01-25 14:49:24 +01005768}
5769
5770/*
5771 * Perform the SSL handshake
5772 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005773int mbedtls_ssl_handshake(mbedtls_ssl_context *ssl)
Paul Bakker1961b702013-01-25 14:49:24 +01005774{
5775 int ret = 0;
5776
Hanno Beckera817ea42020-10-20 15:20:23 +01005777 /* Sanity checks */
5778
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005779 if (ssl == NULL || ssl->conf == NULL) {
5780 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
5781 }
Manuel Pégourié-Gonnardf81ee2e2015-09-01 17:43:40 +02005782
Hanno Beckera817ea42020-10-20 15:20:23 +01005783#if defined(MBEDTLS_SSL_PROTO_DTLS)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005784 if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
5785 (ssl->f_set_timer == NULL || ssl->f_get_timer == NULL)) {
5786 MBEDTLS_SSL_DEBUG_MSG(1, ("You must use "
5787 "mbedtls_ssl_set_timer_cb() for DTLS"));
5788 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
Hanno Beckera817ea42020-10-20 15:20:23 +01005789 }
5790#endif /* MBEDTLS_SSL_PROTO_DTLS */
5791
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005792 MBEDTLS_SSL_DEBUG_MSG(2, ("=> handshake"));
Paul Bakker1961b702013-01-25 14:49:24 +01005793
Hanno Beckera817ea42020-10-20 15:20:23 +01005794 /* Main handshake loop */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005795 while (ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER) {
5796 ret = mbedtls_ssl_handshake_step(ssl);
Paul Bakker1961b702013-01-25 14:49:24 +01005797
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005798 if (ret != 0) {
Paul Bakker1961b702013-01-25 14:49:24 +01005799 break;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005800 }
Paul Bakker1961b702013-01-25 14:49:24 +01005801 }
5802
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005803 MBEDTLS_SSL_DEBUG_MSG(2, ("<= handshake"));
Paul Bakker5121ce52009-01-03 21:22:43 +00005804
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005805 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00005806}
5807
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005808#if defined(MBEDTLS_SSL_RENEGOTIATION)
5809#if defined(MBEDTLS_SSL_SRV_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00005810/*
Manuel Pégourié-Gonnard214eed32013-10-30 13:06:54 +01005811 * Write HelloRequest to request renegotiation on server
Paul Bakker48916f92012-09-16 19:57:18 +00005812 */
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +02005813MBEDTLS_CHECK_RETURN_CRITICAL
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005814static int ssl_write_hello_request(mbedtls_ssl_context *ssl)
Manuel Pégourié-Gonnard214eed32013-10-30 13:06:54 +01005815{
Janos Follath865b3eb2019-12-16 11:46:15 +00005816 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard214eed32013-10-30 13:06:54 +01005817
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005818 MBEDTLS_SSL_DEBUG_MSG(2, ("=> write hello request"));
Manuel Pégourié-Gonnard214eed32013-10-30 13:06:54 +01005819
5820 ssl->out_msglen = 4;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005821 ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
5822 ssl->out_msg[0] = MBEDTLS_SSL_HS_HELLO_REQUEST;
Manuel Pégourié-Gonnard214eed32013-10-30 13:06:54 +01005823
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005824 if ((ret = mbedtls_ssl_write_handshake_msg(ssl)) != 0) {
5825 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_handshake_msg", ret);
5826 return ret;
Manuel Pégourié-Gonnard214eed32013-10-30 13:06:54 +01005827 }
5828
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005829 MBEDTLS_SSL_DEBUG_MSG(2, ("<= write hello request"));
Manuel Pégourié-Gonnard214eed32013-10-30 13:06:54 +01005830
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005831 return 0;
Manuel Pégourié-Gonnard214eed32013-10-30 13:06:54 +01005832}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005833#endif /* MBEDTLS_SSL_SRV_C */
Manuel Pégourié-Gonnard214eed32013-10-30 13:06:54 +01005834
5835/*
5836 * Actually renegotiate current connection, triggered by either:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005837 * - any side: calling mbedtls_ssl_renegotiate(),
5838 * - client: receiving a HelloRequest during mbedtls_ssl_read(),
5839 * - server: receiving any handshake message on server during mbedtls_ssl_read() after
Manuel Pégourié-Gonnard55e4ff22014-08-19 11:16:35 +02005840 * the initial handshake is completed.
Manuel Pégourié-Gonnard9c1e1892013-10-30 16:41:21 +01005841 * If the handshake doesn't complete due to waiting for I/O, it will continue
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005842 * during the next calls to mbedtls_ssl_renegotiate() or mbedtls_ssl_read() respectively.
Manuel Pégourié-Gonnard214eed32013-10-30 13:06:54 +01005843 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005844int mbedtls_ssl_start_renegotiation(mbedtls_ssl_context *ssl)
Paul Bakker48916f92012-09-16 19:57:18 +00005845{
Janos Follath865b3eb2019-12-16 11:46:15 +00005846 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker48916f92012-09-16 19:57:18 +00005847
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005848 MBEDTLS_SSL_DEBUG_MSG(2, ("=> renegotiate"));
Paul Bakker48916f92012-09-16 19:57:18 +00005849
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005850 if ((ret = ssl_handshake_init(ssl)) != 0) {
5851 return ret;
5852 }
Paul Bakker48916f92012-09-16 19:57:18 +00005853
Manuel Pégourié-Gonnard0557bd52014-08-19 19:18:39 +02005854 /* RFC 6347 4.2.2: "[...] the HelloRequest will have message_seq = 0 and
5855 * the ServerHello will have message_seq = 1" */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005856#if defined(MBEDTLS_SSL_PROTO_DTLS)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005857 if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
5858 ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING) {
5859 if (ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER) {
Manuel Pégourié-Gonnard1aa586e2014-09-03 12:54:04 +02005860 ssl->handshake->out_msg_seq = 1;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005861 } else {
Manuel Pégourié-Gonnard1aa586e2014-09-03 12:54:04 +02005862 ssl->handshake->in_msg_seq = 1;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005863 }
Manuel Pégourié-Gonnard0557bd52014-08-19 19:18:39 +02005864 }
5865#endif
5866
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005867 ssl->state = MBEDTLS_SSL_HELLO_REQUEST;
5868 ssl->renego_status = MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS;
Paul Bakker48916f92012-09-16 19:57:18 +00005869
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005870 if ((ret = mbedtls_ssl_handshake(ssl)) != 0) {
5871 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_handshake", ret);
5872 return ret;
Paul Bakker48916f92012-09-16 19:57:18 +00005873 }
5874
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005875 MBEDTLS_SSL_DEBUG_MSG(2, ("<= renegotiate"));
Paul Bakker48916f92012-09-16 19:57:18 +00005876
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005877 return 0;
Paul Bakker48916f92012-09-16 19:57:18 +00005878}
5879
5880/*
Manuel Pégourié-Gonnard214eed32013-10-30 13:06:54 +01005881 * Renegotiate current connection on client,
5882 * or request renegotiation on server
5883 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005884int mbedtls_ssl_renegotiate(mbedtls_ssl_context *ssl)
Manuel Pégourié-Gonnard214eed32013-10-30 13:06:54 +01005885{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005886 int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
Manuel Pégourié-Gonnard9c1e1892013-10-30 16:41:21 +01005887
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005888 if (ssl == NULL || ssl->conf == NULL) {
5889 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
5890 }
Manuel Pégourié-Gonnardf81ee2e2015-09-01 17:43:40 +02005891
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005892#if defined(MBEDTLS_SSL_SRV_C)
Manuel Pégourié-Gonnard9c1e1892013-10-30 16:41:21 +01005893 /* On server, just send the request */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005894 if (ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER) {
5895 if (ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER) {
5896 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
5897 }
Manuel Pégourié-Gonnard9c1e1892013-10-30 16:41:21 +01005898
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005899 ssl->renego_status = MBEDTLS_SSL_RENEGOTIATION_PENDING;
Manuel Pégourié-Gonnardf07f4212014-08-15 19:04:47 +02005900
5901 /* Did we already try/start sending HelloRequest? */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005902 if (ssl->out_left != 0) {
5903 return mbedtls_ssl_flush_output(ssl);
5904 }
Manuel Pégourié-Gonnardf07f4212014-08-15 19:04:47 +02005905
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005906 return ssl_write_hello_request(ssl);
Manuel Pégourié-Gonnard9c1e1892013-10-30 16:41:21 +01005907 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005908#endif /* MBEDTLS_SSL_SRV_C */
Manuel Pégourié-Gonnard9c1e1892013-10-30 16:41:21 +01005909
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005910#if defined(MBEDTLS_SSL_CLI_C)
Manuel Pégourié-Gonnard9c1e1892013-10-30 16:41:21 +01005911 /*
5912 * On client, either start the renegotiation process or,
5913 * if already in progress, continue the handshake
5914 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005915 if (ssl->renego_status != MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS) {
5916 if (ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER) {
5917 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
Manuel Pégourié-Gonnard9c1e1892013-10-30 16:41:21 +01005918 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005919
5920 if ((ret = mbedtls_ssl_start_renegotiation(ssl)) != 0) {
5921 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_start_renegotiation", ret);
5922 return ret;
5923 }
5924 } else {
5925 if ((ret = mbedtls_ssl_handshake(ssl)) != 0) {
5926 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_handshake", ret);
5927 return ret;
Manuel Pégourié-Gonnard9c1e1892013-10-30 16:41:21 +01005928 }
5929 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005930#endif /* MBEDTLS_SSL_CLI_C */
Manuel Pégourié-Gonnard9c1e1892013-10-30 16:41:21 +01005931
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005932 return ret;
Manuel Pégourié-Gonnard214eed32013-10-30 13:06:54 +01005933}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005934#endif /* MBEDTLS_SSL_RENEGOTIATION */
Manuel Pégourié-Gonnard214eed32013-10-30 13:06:54 +01005935
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005936#if defined(MBEDTLS_X509_CRT_PARSE_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005937static void ssl_key_cert_free(mbedtls_ssl_key_cert *key_cert)
Manuel Pégourié-Gonnard705fcca2013-09-23 20:04:20 +02005938{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005939 mbedtls_ssl_key_cert *cur = key_cert, *next;
Manuel Pégourié-Gonnard705fcca2013-09-23 20:04:20 +02005940
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005941 while (cur != NULL) {
Manuel Pégourié-Gonnard705fcca2013-09-23 20:04:20 +02005942 next = cur->next;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005943 mbedtls_free(cur);
Manuel Pégourié-Gonnard705fcca2013-09-23 20:04:20 +02005944 cur = next;
5945 }
5946}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005947#endif /* MBEDTLS_X509_CRT_PARSE_C */
Manuel Pégourié-Gonnard705fcca2013-09-23 20:04:20 +02005948
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005949void mbedtls_ssl_handshake_free(mbedtls_ssl_context *ssl)
Paul Bakker48916f92012-09-16 19:57:18 +00005950{
Gilles Peskine9b562d52018-04-25 20:32:43 +02005951 mbedtls_ssl_handshake_params *handshake = ssl->handshake;
5952
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005953 if (handshake == NULL) {
Paul Bakkeraccaffe2014-06-26 13:37:14 +02005954 return;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005955 }
Paul Bakkeraccaffe2014-06-26 13:37:14 +02005956
Gilles Peskinedf13d5c2018-04-25 20:39:48 +02005957#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005958 if (ssl->conf->f_async_cancel != NULL && handshake->async_in_progress != 0) {
5959 ssl->conf->f_async_cancel(ssl);
Gilles Peskinedf13d5c2018-04-25 20:39:48 +02005960 handshake->async_in_progress = 0;
5961 }
5962#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
5963
Manuel Pégourié-Gonnardb9d64e52015-07-06 14:18:56 +02005964#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
5965 defined(MBEDTLS_SSL_PROTO_TLS1_1)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005966 mbedtls_md5_free(&handshake->fin_md5);
5967 mbedtls_sha1_free(&handshake->fin_sha1);
Manuel Pégourié-Gonnardb9d64e52015-07-06 14:18:56 +02005968#endif
5969#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
5970#if defined(MBEDTLS_SHA256_C)
Andrzej Kurekeb342242019-01-29 09:14:33 -05005971#if defined(MBEDTLS_USE_PSA_CRYPTO)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005972 psa_hash_abort(&handshake->fin_sha256_psa);
Andrzej Kurekeb342242019-01-29 09:14:33 -05005973#else
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005974 mbedtls_sha256_free(&handshake->fin_sha256);
Manuel Pégourié-Gonnardb9d64e52015-07-06 14:18:56 +02005975#endif
Andrzej Kurekeb342242019-01-29 09:14:33 -05005976#endif
Gilles Peskined2d59372021-05-12 22:43:27 +02005977#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384)
Andrzej Kurekeb342242019-01-29 09:14:33 -05005978#if defined(MBEDTLS_USE_PSA_CRYPTO)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005979 psa_hash_abort(&handshake->fin_sha384_psa);
Andrzej Kurekeb342242019-01-29 09:14:33 -05005980#else
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005981 mbedtls_sha512_free(&handshake->fin_sha512);
Manuel Pégourié-Gonnardb9d64e52015-07-06 14:18:56 +02005982#endif
Andrzej Kurekeb342242019-01-29 09:14:33 -05005983#endif
Manuel Pégourié-Gonnardb9d64e52015-07-06 14:18:56 +02005984#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
5985
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005986#if defined(MBEDTLS_DHM_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005987 mbedtls_dhm_free(&handshake->dhm_ctx);
Paul Bakker48916f92012-09-16 19:57:18 +00005988#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005989#if defined(MBEDTLS_ECDH_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005990 mbedtls_ecdh_free(&handshake->ecdh_ctx);
Paul Bakker61d113b2013-07-04 11:51:43 +02005991#endif
Manuel Pégourié-Gonnardeef142d2015-09-16 10:05:04 +02005992#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005993 mbedtls_ecjpake_free(&handshake->ecjpake_ctx);
Manuel Pégourié-Gonnard77c06462015-09-17 13:59:49 +02005994#if defined(MBEDTLS_SSL_CLI_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01005995 mbedtls_free(handshake->ecjpake_cache);
Manuel Pégourié-Gonnard77c06462015-09-17 13:59:49 +02005996 handshake->ecjpake_cache = NULL;
5997 handshake->ecjpake_cache_len = 0;
5998#endif
Manuel Pégourié-Gonnard76cfd3f2015-09-15 12:10:54 +02005999#endif
Paul Bakker61d113b2013-07-04 11:51:43 +02006000
Janos Follath4ae5c292016-02-10 11:27:43 +00006001#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
6002 defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
Paul Bakker9af723c2014-05-01 13:03:14 +02006003 /* explicit void pointer cast for buggy MS compiler */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006004 mbedtls_free((void *) handshake->curves);
Manuel Pégourié-Gonnardd09453c2013-09-23 19:11:32 +02006005#endif
6006
Gilles Peskineeccd8882020-03-10 12:19:08 +01006007#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006008 if (handshake->psk != NULL) {
6009 mbedtls_platform_zeroize(handshake->psk, handshake->psk_len);
6010 mbedtls_free(handshake->psk);
Manuel Pégourié-Gonnard4b682962015-05-07 15:59:54 +01006011 }
6012#endif
6013
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02006014#if defined(MBEDTLS_X509_CRT_PARSE_C) && \
6015 defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
Manuel Pégourié-Gonnard83724542013-09-24 22:30:56 +02006016 /*
6017 * Free only the linked list wrapper, not the keys themselves
6018 * since the belong to the SNI callback
6019 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006020 if (handshake->sni_key_cert != NULL) {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02006021 mbedtls_ssl_key_cert *cur = handshake->sni_key_cert, *next;
Manuel Pégourié-Gonnard83724542013-09-24 22:30:56 +02006022
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006023 while (cur != NULL) {
Manuel Pégourié-Gonnard83724542013-09-24 22:30:56 +02006024 next = cur->next;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006025 mbedtls_free(cur);
Manuel Pégourié-Gonnard83724542013-09-24 22:30:56 +02006026 cur = next;
6027 }
6028 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02006029#endif /* MBEDTLS_X509_CRT_PARSE_C && MBEDTLS_SSL_SERVER_NAME_INDICATION */
Manuel Pégourié-Gonnard705fcca2013-09-23 20:04:20 +02006030
Gilles Peskineeccd8882020-03-10 12:19:08 +01006031#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006032 mbedtls_x509_crt_restart_free(&handshake->ecrs_ctx);
6033 if (handshake->ecrs_peer_cert != NULL) {
6034 mbedtls_x509_crt_free(handshake->ecrs_peer_cert);
6035 mbedtls_free(handshake->ecrs_peer_cert);
Hanno Becker3dad3112019-02-05 17:19:52 +00006036 }
Manuel Pégourié-Gonnard862cde52017-05-17 11:56:15 +02006037#endif
6038
Hanno Becker75173122019-02-06 16:18:31 +00006039#if defined(MBEDTLS_X509_CRT_PARSE_C) && \
6040 !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006041 mbedtls_pk_free(&handshake->peer_pubkey);
Hanno Becker75173122019-02-06 16:18:31 +00006042#endif /* MBEDTLS_X509_CRT_PARSE_C && !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
6043
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02006044#if defined(MBEDTLS_SSL_PROTO_DTLS)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006045 mbedtls_free(handshake->verify_cookie);
6046 mbedtls_ssl_flight_free(handshake->flight);
6047 mbedtls_ssl_buffering_free(ssl);
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +02006048#endif
6049
Hanno Becker4a63ed42019-01-08 11:39:35 +00006050#if defined(MBEDTLS_ECDH_C) && \
6051 defined(MBEDTLS_USE_PSA_CRYPTO)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006052 psa_destroy_key(handshake->ecdh_psa_privkey);
Hanno Becker4a63ed42019-01-08 11:39:35 +00006053#endif /* MBEDTLS_ECDH_C && MBEDTLS_USE_PSA_CRYPTO */
6054
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006055 mbedtls_platform_zeroize(handshake,
6056 sizeof(mbedtls_ssl_handshake_params));
Andrzej Kurek0afa2a12020-03-03 10:39:58 -05006057
6058#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
6059 /* If the buffers are too big - reallocate. Because of the way Mbed TLS
6060 * processes datagrams and the fact that a datagram is allowed to have
6061 * several records in it, it is possible that the I/O buffers are not
6062 * empty at this stage */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006063 handle_buffer_resizing(ssl, 1, mbedtls_ssl_get_input_buflen(ssl),
6064 mbedtls_ssl_get_output_buflen(ssl));
Andrzej Kurek0afa2a12020-03-03 10:39:58 -05006065#endif
Paul Bakker48916f92012-09-16 19:57:18 +00006066}
6067
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006068void mbedtls_ssl_session_free(mbedtls_ssl_session *session)
Paul Bakker48916f92012-09-16 19:57:18 +00006069{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006070 if (session == NULL) {
Paul Bakkeraccaffe2014-06-26 13:37:14 +02006071 return;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006072 }
Paul Bakkeraccaffe2014-06-26 13:37:14 +02006073
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02006074#if defined(MBEDTLS_X509_CRT_PARSE_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006075 ssl_clear_peer_cert(session);
Paul Bakkered27a042013-04-18 22:46:23 +02006076#endif
Paul Bakker0a597072012-09-25 21:55:46 +00006077
Manuel Pégourié-Gonnardb596abf2015-05-20 10:45:29 +02006078#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006079 mbedtls_free(session->ticket);
Paul Bakkera503a632013-08-14 13:48:06 +02006080#endif
Manuel Pégourié-Gonnard75d44012013-08-02 14:44:04 +02006081
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006082 mbedtls_platform_zeroize(session, sizeof(mbedtls_ssl_session));
Paul Bakker48916f92012-09-16 19:57:18 +00006083}
6084
Manuel Pégourié-Gonnard5c0e3772019-07-23 16:13:17 +02006085#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION)
Manuel Pégourié-Gonnard4e9370b2019-07-23 16:31:16 +02006086
6087#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
6088#define SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_CONNECTION_ID 1u
6089#else
6090#define SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_CONNECTION_ID 0u
6091#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
6092
6093#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT)
6094#define SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_BADMAC_LIMIT 1u
6095#else
6096#define SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_BADMAC_LIMIT 0u
6097#endif /* MBEDTLS_SSL_DTLS_BADMAC_LIMIT */
6098
6099#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
6100#define SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_ANTI_REPLAY 1u
6101#else
6102#define SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_ANTI_REPLAY 0u
6103#endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */
6104
6105#if defined(MBEDTLS_SSL_ALPN)
6106#define SSL_SERIALIZED_CONTEXT_CONFIG_ALPN 1u
6107#else
6108#define SSL_SERIALIZED_CONTEXT_CONFIG_ALPN 0u
6109#endif /* MBEDTLS_SSL_ALPN */
6110
6111#define SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_CONNECTION_ID_BIT 0
6112#define SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_BADMAC_LIMIT_BIT 1
6113#define SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_ANTI_REPLAY_BIT 2
6114#define SSL_SERIALIZED_CONTEXT_CONFIG_ALPN_BIT 3
6115
6116#define SSL_SERIALIZED_CONTEXT_CONFIG_BITFLAG \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006117 ((uint32_t) ( \
6118 (SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_CONNECTION_ID << \
6119 SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_CONNECTION_ID_BIT) | \
6120 (SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_BADMAC_LIMIT << \
6121 SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_BADMAC_LIMIT_BIT) | \
6122 (SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_ANTI_REPLAY << \
6123 SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_ANTI_REPLAY_BIT) | \
6124 (SSL_SERIALIZED_CONTEXT_CONFIG_ALPN << SSL_SERIALIZED_CONTEXT_CONFIG_ALPN_BIT) | \
6125 0u))
Manuel Pégourié-Gonnard4e9370b2019-07-23 16:31:16 +02006126
Manuel Pégourié-Gonnard4c90e852019-07-11 10:58:10 +02006127static unsigned char ssl_serialized_context_header[] = {
6128 MBEDTLS_VERSION_MAJOR,
6129 MBEDTLS_VERSION_MINOR,
6130 MBEDTLS_VERSION_PATCH,
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006131 MBEDTLS_BYTE_1(SSL_SERIALIZED_SESSION_CONFIG_BITFLAG),
6132 MBEDTLS_BYTE_0(SSL_SERIALIZED_SESSION_CONFIG_BITFLAG),
6133 MBEDTLS_BYTE_2(SSL_SERIALIZED_CONTEXT_CONFIG_BITFLAG),
6134 MBEDTLS_BYTE_1(SSL_SERIALIZED_CONTEXT_CONFIG_BITFLAG),
6135 MBEDTLS_BYTE_0(SSL_SERIALIZED_CONTEXT_CONFIG_BITFLAG),
Manuel Pégourié-Gonnard4c90e852019-07-11 10:58:10 +02006136};
6137
Paul Bakker5121ce52009-01-03 21:22:43 +00006138/*
Manuel Pégourié-Gonnardac87e282019-05-28 13:02:16 +02006139 * Serialize a full SSL context
Manuel Pégourié-Gonnard00400c22019-07-10 14:58:45 +02006140 *
6141 * The format of the serialized data is:
6142 * (in the presentation language of TLS, RFC 8446 section 3)
6143 *
6144 * // header
6145 * opaque mbedtls_version[3]; // major, minor, patch
Manuel Pégourié-Gonnard4c90e852019-07-11 10:58:10 +02006146 * opaque context_format[5]; // version-specific field determining
Manuel Pégourié-Gonnard00400c22019-07-10 14:58:45 +02006147 * // the format of the remaining
Manuel Pégourié-Gonnard4c90e852019-07-11 10:58:10 +02006148 * // serialized data.
Manuel Pégourié-Gonnard4e9370b2019-07-23 16:31:16 +02006149 * Note: When updating the format, remember to keep these
6150 * version+format bytes. (We may make their size part of the API.)
Manuel Pégourié-Gonnard00400c22019-07-10 14:58:45 +02006151 *
6152 * // session sub-structure
6153 * opaque session<1..2^32-1>; // see mbedtls_ssl_session_save()
6154 * // transform sub-structure
6155 * uint8 random[64]; // ServerHello.random+ClientHello.random
6156 * uint8 in_cid<0..2^8-1> // Connection ID: expected incoming value
6157 * uint8 out_cid<0..2^8-1> // Connection ID: outgoing value to use
6158 * // fields from ssl_context
6159 * uint32 badmac_seen; // DTLS: number of records with failing MAC
6160 * uint64 in_window_top; // DTLS: last validated record seq_num
6161 * uint64 in_window; // DTLS: bitmask for replay protection
6162 * uint8 disable_datagram_packing; // DTLS: only one record per datagram
6163 * uint64 cur_out_ctr; // Record layer: outgoing sequence number
6164 * uint16 mtu; // DTLS: path mtu (max outgoing fragment size)
6165 * uint8 alpn_chosen<0..2^8-1> // ALPN: negotiated application protocol
6166 *
6167 * Note that many fields of the ssl_context or sub-structures are not
6168 * serialized, as they fall in one of the following categories:
6169 *
6170 * 1. forced value (eg in_left must be 0)
6171 * 2. pointer to dynamically-allocated memory (eg session, transform)
6172 * 3. value can be re-derived from other data (eg session keys from MS)
6173 * 4. value was temporary (eg content of input buffer)
6174 * 5. value will be provided by the user again (eg I/O callbacks and context)
Manuel Pégourié-Gonnardac87e282019-05-28 13:02:16 +02006175 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006176int mbedtls_ssl_context_save(mbedtls_ssl_context *ssl,
6177 unsigned char *buf,
6178 size_t buf_len,
6179 size_t *olen)
Manuel Pégourié-Gonnardac87e282019-05-28 13:02:16 +02006180{
Manuel Pégourié-Gonnard4c90e852019-07-11 10:58:10 +02006181 unsigned char *p = buf;
6182 size_t used = 0;
Manuel Pégourié-Gonnard4b7e6b92019-07-11 12:50:53 +02006183 size_t session_len;
6184 int ret = 0;
Manuel Pégourié-Gonnard4c90e852019-07-11 10:58:10 +02006185
Manuel Pégourié-Gonnard1aaf6692019-07-10 14:14:05 +02006186 /*
Manuel Pégourié-Gonnarde4588692019-07-29 12:28:52 +02006187 * Enforce usage restrictions, see "return BAD_INPUT_DATA" in
6188 * this function's documentation.
6189 *
6190 * These are due to assumptions/limitations in the implementation. Some of
6191 * them are likely to stay (no handshake in progress) some might go away
6192 * (only DTLS) but are currently used to simplify the implementation.
Manuel Pégourié-Gonnard1aaf6692019-07-10 14:14:05 +02006193 */
Manuel Pégourié-Gonnarde4588692019-07-29 12:28:52 +02006194 /* The initial handshake must be over */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006195 if (ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER) {
6196 MBEDTLS_SSL_DEBUG_MSG(1, ("Initial handshake isn't over"));
6197 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
Jarno Lamsa8c51b7c2019-08-21 13:45:05 +03006198 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006199 if (ssl->handshake != NULL) {
6200 MBEDTLS_SSL_DEBUG_MSG(1, ("Handshake isn't completed"));
6201 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
Jarno Lamsa8c51b7c2019-08-21 13:45:05 +03006202 }
Manuel Pégourié-Gonnarde4588692019-07-29 12:28:52 +02006203 /* Double-check that sub-structures are indeed ready */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006204 if (ssl->transform == NULL || ssl->session == NULL) {
6205 MBEDTLS_SSL_DEBUG_MSG(1, ("Serialised structures aren't ready"));
6206 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
Jarno Lamsa8c51b7c2019-08-21 13:45:05 +03006207 }
Manuel Pégourié-Gonnarde4588692019-07-29 12:28:52 +02006208 /* There must be no pending incoming or outgoing data */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006209 if (mbedtls_ssl_check_pending(ssl) != 0) {
6210 MBEDTLS_SSL_DEBUG_MSG(1, ("There is pending incoming data"));
6211 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
Jarno Lamsa8c51b7c2019-08-21 13:45:05 +03006212 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006213 if (ssl->out_left != 0) {
6214 MBEDTLS_SSL_DEBUG_MSG(1, ("There is pending outgoing data"));
6215 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
Jarno Lamsa8c51b7c2019-08-21 13:45:05 +03006216 }
Dave Rodgmana03396a2022-12-06 16:30:38 +00006217 /* Protocol must be DTLS, not TLS */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006218 if (ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
6219 MBEDTLS_SSL_DEBUG_MSG(1, ("Only DTLS is supported"));
6220 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
Jarno Lamsa8c51b7c2019-08-21 13:45:05 +03006221 }
Manuel Pégourié-Gonnarde4588692019-07-29 12:28:52 +02006222 /* Version must be 1.2 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006223 if (ssl->major_ver != MBEDTLS_SSL_MAJOR_VERSION_3) {
6224 MBEDTLS_SSL_DEBUG_MSG(1, ("Only version 1.2 supported"));
6225 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
Jarno Lamsa8c51b7c2019-08-21 13:45:05 +03006226 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006227 if (ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_3) {
6228 MBEDTLS_SSL_DEBUG_MSG(1, ("Only version 1.2 supported"));
6229 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
Jarno Lamsa8c51b7c2019-08-21 13:45:05 +03006230 }
Manuel Pégourié-Gonnarde4588692019-07-29 12:28:52 +02006231 /* We must be using an AEAD ciphersuite */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006232 if (mbedtls_ssl_transform_uses_aead(ssl->transform) != 1) {
6233 MBEDTLS_SSL_DEBUG_MSG(1, ("Only AEAD ciphersuites supported"));
6234 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
Jarno Lamsa8c51b7c2019-08-21 13:45:05 +03006235 }
Manuel Pégourié-Gonnarde4588692019-07-29 12:28:52 +02006236 /* Renegotiation must not be enabled */
6237#if defined(MBEDTLS_SSL_RENEGOTIATION)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006238 if (ssl->conf->disable_renegotiation != MBEDTLS_SSL_RENEGOTIATION_DISABLED) {
6239 MBEDTLS_SSL_DEBUG_MSG(1, ("Renegotiation must not be enabled"));
6240 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
Jarno Lamsa8c51b7c2019-08-21 13:45:05 +03006241 }
Manuel Pégourié-Gonnarde4588692019-07-29 12:28:52 +02006242#endif
Manuel Pégourié-Gonnardac87e282019-05-28 13:02:16 +02006243
Manuel Pégourié-Gonnard4c90e852019-07-11 10:58:10 +02006244 /*
6245 * Version and format identifier
6246 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006247 used += sizeof(ssl_serialized_context_header);
Manuel Pégourié-Gonnardac87e282019-05-28 13:02:16 +02006248
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006249 if (used <= buf_len) {
6250 memcpy(p, ssl_serialized_context_header,
6251 sizeof(ssl_serialized_context_header));
6252 p += sizeof(ssl_serialized_context_header);
Manuel Pégourié-Gonnard4c90e852019-07-11 10:58:10 +02006253 }
6254
6255 /*
Manuel Pégourié-Gonnard4b7e6b92019-07-11 12:50:53 +02006256 * Session (length + data)
6257 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006258 ret = ssl_session_save(ssl->session, 1, NULL, 0, &session_len);
6259 if (ret != MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL) {
6260 return ret;
6261 }
Manuel Pégourié-Gonnard4b7e6b92019-07-11 12:50:53 +02006262
6263 used += 4 + session_len;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006264 if (used <= buf_len) {
6265 MBEDTLS_PUT_UINT32_BE(session_len, p, 0);
Joe Subbiani2f98d792021-08-20 11:44:44 +01006266 p += 4;
Manuel Pégourié-Gonnard4b7e6b92019-07-11 12:50:53 +02006267
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006268 ret = ssl_session_save(ssl->session, 1,
6269 p, session_len, &session_len);
6270 if (ret != 0) {
6271 return ret;
6272 }
Manuel Pégourié-Gonnard4b7e6b92019-07-11 12:50:53 +02006273
6274 p += session_len;
6275 }
6276
6277 /*
Manuel Pégourié-Gonnardc2a7b892019-07-15 09:04:11 +02006278 * Transform
6279 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006280 used += sizeof(ssl->transform->randbytes);
6281 if (used <= buf_len) {
6282 memcpy(p, ssl->transform->randbytes,
6283 sizeof(ssl->transform->randbytes));
6284 p += sizeof(ssl->transform->randbytes);
Manuel Pégourié-Gonnardc2a7b892019-07-15 09:04:11 +02006285 }
6286
6287#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
6288 used += 2 + ssl->transform->in_cid_len + ssl->transform->out_cid_len;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006289 if (used <= buf_len) {
Manuel Pégourié-Gonnardc2a7b892019-07-15 09:04:11 +02006290 *p++ = ssl->transform->in_cid_len;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006291 memcpy(p, ssl->transform->in_cid, ssl->transform->in_cid_len);
Manuel Pégourié-Gonnardc2a7b892019-07-15 09:04:11 +02006292 p += ssl->transform->in_cid_len;
6293
6294 *p++ = ssl->transform->out_cid_len;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006295 memcpy(p, ssl->transform->out_cid, ssl->transform->out_cid_len);
Manuel Pégourié-Gonnardc2a7b892019-07-15 09:04:11 +02006296 p += ssl->transform->out_cid_len;
6297 }
6298#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
6299
6300 /*
Manuel Pégourié-Gonnardc86c5df2019-07-15 11:23:03 +02006301 * Saved fields from top-level ssl_context structure
6302 */
6303#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT)
6304 used += 4;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006305 if (used <= buf_len) {
6306 MBEDTLS_PUT_UINT32_BE(ssl->badmac_seen, p, 0);
Joe Subbiani2f98d792021-08-20 11:44:44 +01006307 p += 4;
Manuel Pégourié-Gonnardc86c5df2019-07-15 11:23:03 +02006308 }
6309#endif /* MBEDTLS_SSL_DTLS_BADMAC_LIMIT */
6310
6311#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
6312 used += 16;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006313 if (used <= buf_len) {
6314 MBEDTLS_PUT_UINT64_BE(ssl->in_window_top, p, 0);
Joe Subbiani2f98d792021-08-20 11:44:44 +01006315 p += 8;
Manuel Pégourié-Gonnardc86c5df2019-07-15 11:23:03 +02006316
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006317 MBEDTLS_PUT_UINT64_BE(ssl->in_window, p, 0);
Joe Subbiani2f98d792021-08-20 11:44:44 +01006318 p += 8;
Manuel Pégourié-Gonnardc86c5df2019-07-15 11:23:03 +02006319 }
6320#endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */
6321
6322#if defined(MBEDTLS_SSL_PROTO_DTLS)
6323 used += 1;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006324 if (used <= buf_len) {
Manuel Pégourié-Gonnardc86c5df2019-07-15 11:23:03 +02006325 *p++ = ssl->disable_datagram_packing;
6326 }
6327#endif /* MBEDTLS_SSL_PROTO_DTLS */
6328
6329 used += 8;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006330 if (used <= buf_len) {
6331 memcpy(p, ssl->cur_out_ctr, 8);
Manuel Pégourié-Gonnardc86c5df2019-07-15 11:23:03 +02006332 p += 8;
6333 }
6334
6335#if defined(MBEDTLS_SSL_PROTO_DTLS)
6336 used += 2;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006337 if (used <= buf_len) {
6338 MBEDTLS_PUT_UINT16_BE(ssl->mtu, p, 0);
Joe Subbiani2f98d792021-08-20 11:44:44 +01006339 p += 2;
Manuel Pégourié-Gonnardc86c5df2019-07-15 11:23:03 +02006340 }
6341#endif /* MBEDTLS_SSL_PROTO_DTLS */
6342
6343#if defined(MBEDTLS_SSL_ALPN)
6344 {
6345 const uint8_t alpn_len = ssl->alpn_chosen
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006346 ? (uint8_t) strlen(ssl->alpn_chosen)
Manuel Pégourié-Gonnardc86c5df2019-07-15 11:23:03 +02006347 : 0;
6348
6349 used += 1 + alpn_len;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006350 if (used <= buf_len) {
Manuel Pégourié-Gonnardc86c5df2019-07-15 11:23:03 +02006351 *p++ = alpn_len;
6352
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006353 if (ssl->alpn_chosen != NULL) {
6354 memcpy(p, ssl->alpn_chosen, alpn_len);
Manuel Pégourié-Gonnardc86c5df2019-07-15 11:23:03 +02006355 p += alpn_len;
6356 }
6357 }
6358 }
6359#endif /* MBEDTLS_SSL_ALPN */
6360
6361 /*
Manuel Pégourié-Gonnard4c90e852019-07-11 10:58:10 +02006362 * Done
6363 */
6364 *olen = used;
6365
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006366 if (used > buf_len) {
6367 return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL;
6368 }
Manuel Pégourié-Gonnardac87e282019-05-28 13:02:16 +02006369
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006370 MBEDTLS_SSL_DEBUG_BUF(4, "saved context", buf, used);
Manuel Pégourié-Gonnard4b7e6b92019-07-11 12:50:53 +02006371
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006372 return mbedtls_ssl_session_reset_int(ssl, 0);
Manuel Pégourié-Gonnardac87e282019-05-28 13:02:16 +02006373}
6374
6375/*
Manuel Pégourié-Gonnardc2a7b892019-07-15 09:04:11 +02006376 * Helper to get TLS 1.2 PRF from ciphersuite
6377 * (Duplicates bits of logic from ssl_set_handshake_prfs().)
6378 */
Andrzej Kurekf9412f72022-10-18 07:30:19 -04006379#if defined(MBEDTLS_SHA256_C) || \
6380 (defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384))
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006381typedef int (*tls_prf_fn)(const unsigned char *secret, size_t slen,
6382 const char *label,
6383 const unsigned char *random, size_t rlen,
6384 unsigned char *dstbuf, size_t dlen);
6385static tls_prf_fn ssl_tls12prf_from_cs(int ciphersuite_id)
Manuel Pégourié-Gonnardc2a7b892019-07-15 09:04:11 +02006386{
6387 const mbedtls_ssl_ciphersuite_t * const ciphersuite_info =
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006388 mbedtls_ssl_ciphersuite_from_id(ciphersuite_id);
Manuel Pégourié-Gonnardc2a7b892019-07-15 09:04:11 +02006389
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006390 if (ciphersuite_info == NULL) {
6391 return NULL;
6392 }
Andrzej Kurek84fc52c2022-10-25 04:18:30 -04006393
6394#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006395 if (ciphersuite_info->mac == MBEDTLS_MD_SHA384) {
6396 return tls_prf_sha384;
6397 } else
Manuel Pégourié-Gonnard9a96fd72019-07-23 17:11:24 +02006398#endif
Andrzej Kurekf9412f72022-10-18 07:30:19 -04006399#if defined(MBEDTLS_SHA256_C)
6400 {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006401 if (ciphersuite_info->mac == MBEDTLS_MD_SHA256) {
6402 return tls_prf_sha256;
6403 }
Andrzej Kurekf9412f72022-10-18 07:30:19 -04006404 }
6405#endif
6406#if !defined(MBEDTLS_SHA256_C) && \
6407 (!defined(MBEDTLS_SHA512_C) || defined(MBEDTLS_SHA512_NO_SHA384))
6408 (void) ciphersuite_info;
6409#endif
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006410 return NULL;
Manuel Pégourié-Gonnardc2a7b892019-07-15 09:04:11 +02006411}
6412
Andrzej Kurekf9412f72022-10-18 07:30:19 -04006413#endif /* MBEDTLS_SHA256_C ||
6414 (MBEDTLS_SHA512_C && !MBEDTLS_SHA512_NO_SHA384) */
6415
Manuel Pégourié-Gonnardc2a7b892019-07-15 09:04:11 +02006416/*
Manuel Pégourié-Gonnardb9dfc9f2019-07-12 10:50:19 +02006417 * Deserialize context, see mbedtls_ssl_context_save() for format.
Manuel Pégourié-Gonnard4b7e6b92019-07-11 12:50:53 +02006418 *
6419 * This internal version is wrapped by a public function that cleans up in
6420 * case of error.
Manuel Pégourié-Gonnardac87e282019-05-28 13:02:16 +02006421 */
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +02006422MBEDTLS_CHECK_RETURN_CRITICAL
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006423static int ssl_context_load(mbedtls_ssl_context *ssl,
6424 const unsigned char *buf,
6425 size_t len)
Manuel Pégourié-Gonnardac87e282019-05-28 13:02:16 +02006426{
Manuel Pégourié-Gonnard4c90e852019-07-11 10:58:10 +02006427 const unsigned char *p = buf;
6428 const unsigned char * const end = buf + len;
Manuel Pégourié-Gonnard4b7e6b92019-07-11 12:50:53 +02006429 size_t session_len;
Janos Follath865b3eb2019-12-16 11:46:15 +00006430 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Andrzej Kurekf9412f72022-10-18 07:30:19 -04006431 tls_prf_fn prf_func = NULL;
Manuel Pégourié-Gonnard4c90e852019-07-11 10:58:10 +02006432
Manuel Pégourié-Gonnard0ff76402019-07-11 09:56:30 +02006433 /*
6434 * The context should have been freshly setup or reset.
6435 * Give the user an error in case of obvious misuse.
Manuel Pégourié-Gonnard4ca930f2019-07-26 16:31:53 +02006436 * (Checking session is useful because it won't be NULL if we're
Manuel Pégourié-Gonnard0ff76402019-07-11 09:56:30 +02006437 * renegotiating, or if the user mistakenly loaded a session first.)
6438 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006439 if (ssl->state != MBEDTLS_SSL_HELLO_REQUEST ||
6440 ssl->session != NULL) {
6441 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
Manuel Pégourié-Gonnard0ff76402019-07-11 09:56:30 +02006442 }
6443
6444 /*
6445 * We can't check that the config matches the initial one, but we can at
6446 * least check it matches the requirements for serializing.
6447 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006448 if (ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM ||
Manuel Pégourié-Gonnard0ff76402019-07-11 09:56:30 +02006449 ssl->conf->max_major_ver < MBEDTLS_SSL_MAJOR_VERSION_3 ||
6450 ssl->conf->min_major_ver > MBEDTLS_SSL_MAJOR_VERSION_3 ||
6451 ssl->conf->max_minor_ver < MBEDTLS_SSL_MINOR_VERSION_3 ||
6452 ssl->conf->min_minor_ver > MBEDTLS_SSL_MINOR_VERSION_3 ||
6453#if defined(MBEDTLS_SSL_RENEGOTIATION)
Manuel Pégourié-Gonnard9a96fd72019-07-23 17:11:24 +02006454 ssl->conf->disable_renegotiation != MBEDTLS_SSL_RENEGOTIATION_DISABLED ||
Manuel Pégourié-Gonnard0ff76402019-07-11 09:56:30 +02006455#endif
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006456 0) {
6457 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
Manuel Pégourié-Gonnard0ff76402019-07-11 09:56:30 +02006458 }
6459
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006460 MBEDTLS_SSL_DEBUG_BUF(4, "context to load", buf, len);
Manuel Pégourié-Gonnard4b7e6b92019-07-11 12:50:53 +02006461
Manuel Pégourié-Gonnard4c90e852019-07-11 10:58:10 +02006462 /*
6463 * Check version identifier
6464 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006465 if ((size_t) (end - p) < sizeof(ssl_serialized_context_header)) {
6466 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
Manuel Pégourié-Gonnard4c90e852019-07-11 10:58:10 +02006467 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006468
6469 if (memcmp(p, ssl_serialized_context_header,
6470 sizeof(ssl_serialized_context_header)) != 0) {
6471 return MBEDTLS_ERR_SSL_VERSION_MISMATCH;
6472 }
6473 p += sizeof(ssl_serialized_context_header);
Manuel Pégourié-Gonnard4c90e852019-07-11 10:58:10 +02006474
6475 /*
Manuel Pégourié-Gonnard4b7e6b92019-07-11 12:50:53 +02006476 * Session
6477 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006478 if ((size_t) (end - p) < 4) {
6479 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
6480 }
Manuel Pégourié-Gonnard4b7e6b92019-07-11 12:50:53 +02006481
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006482 session_len = ((size_t) p[0] << 24) |
6483 ((size_t) p[1] << 16) |
6484 ((size_t) p[2] << 8) |
6485 ((size_t) p[3]);
Manuel Pégourié-Gonnard4b7e6b92019-07-11 12:50:53 +02006486 p += 4;
6487
Manuel Pégourié-Gonnard142ba732019-07-23 14:43:30 +02006488 /* This has been allocated by ssl_handshake_init(), called by
Hanno Becker43aefe22020-02-05 10:44:56 +00006489 * by either mbedtls_ssl_session_reset_int() or mbedtls_ssl_setup(). */
Manuel Pégourié-Gonnard142ba732019-07-23 14:43:30 +02006490 ssl->session = ssl->session_negotiate;
Manuel Pégourié-Gonnard4b7e6b92019-07-11 12:50:53 +02006491 ssl->session_in = ssl->session;
6492 ssl->session_out = ssl->session;
Manuel Pégourié-Gonnard142ba732019-07-23 14:43:30 +02006493 ssl->session_negotiate = NULL;
Manuel Pégourié-Gonnard4b7e6b92019-07-11 12:50:53 +02006494
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006495 if ((size_t) (end - p) < session_len) {
6496 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
6497 }
Manuel Pégourié-Gonnard4b7e6b92019-07-11 12:50:53 +02006498
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006499 ret = ssl_session_load(ssl->session, 1, p, session_len);
6500 if (ret != 0) {
6501 mbedtls_ssl_session_free(ssl->session);
6502 return ret;
Manuel Pégourié-Gonnard45ac1f02019-07-23 16:52:45 +02006503 }
Manuel Pégourié-Gonnard4b7e6b92019-07-11 12:50:53 +02006504
6505 p += session_len;
6506
6507 /*
Manuel Pégourié-Gonnardc2a7b892019-07-15 09:04:11 +02006508 * Transform
6509 */
6510
Manuel Pégourié-Gonnard142ba732019-07-23 14:43:30 +02006511 /* This has been allocated by ssl_handshake_init(), called by
Hanno Becker43aefe22020-02-05 10:44:56 +00006512 * by either mbedtls_ssl_session_reset_int() or mbedtls_ssl_setup(). */
Manuel Pégourié-Gonnard142ba732019-07-23 14:43:30 +02006513 ssl->transform = ssl->transform_negotiate;
Manuel Pégourié-Gonnardc2a7b892019-07-15 09:04:11 +02006514 ssl->transform_in = ssl->transform;
6515 ssl->transform_out = ssl->transform;
Manuel Pégourié-Gonnard142ba732019-07-23 14:43:30 +02006516 ssl->transform_negotiate = NULL;
Manuel Pégourié-Gonnardc2a7b892019-07-15 09:04:11 +02006517
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006518 prf_func = ssl_tls12prf_from_cs(ssl->session->ciphersuite);
6519 if (prf_func == NULL) {
6520 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
6521 }
Andrzej Kurekf9412f72022-10-18 07:30:19 -04006522
Manuel Pégourié-Gonnardc2a7b892019-07-15 09:04:11 +02006523 /* Read random bytes and populate structure */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006524 if ((size_t) (end - p) < sizeof(ssl->transform->randbytes)) {
6525 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
6526 }
Manuel Pégourié-Gonnardc2a7b892019-07-15 09:04:11 +02006527
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006528 ret = ssl_populate_transform(ssl->transform,
6529 ssl->session->ciphersuite,
6530 ssl->session->master,
Manuel Pégourié-Gonnardc2a7b892019-07-15 09:04:11 +02006531#if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC)
6532#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006533 ssl->session->encrypt_then_mac,
Manuel Pégourié-Gonnardc2a7b892019-07-15 09:04:11 +02006534#endif
6535#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006536 ssl->session->trunc_hmac,
Manuel Pégourié-Gonnardc2a7b892019-07-15 09:04:11 +02006537#endif
6538#endif /* MBEDTLS_SSL_SOME_MODES_USE_MAC */
6539#if defined(MBEDTLS_ZLIB_SUPPORT)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006540 ssl->session->compression,
Manuel Pégourié-Gonnardc2a7b892019-07-15 09:04:11 +02006541#endif
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006542 prf_func,
6543 p, /* currently pointing to randbytes */
6544 MBEDTLS_SSL_MINOR_VERSION_3, /* (D)TLS 1.2 is forced */
6545 ssl->conf->endpoint,
6546 ssl);
6547 if (ret != 0) {
6548 return ret;
6549 }
Manuel Pégourié-Gonnardc2a7b892019-07-15 09:04:11 +02006550
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006551 p += sizeof(ssl->transform->randbytes);
Manuel Pégourié-Gonnardc2a7b892019-07-15 09:04:11 +02006552
6553#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
6554 /* Read connection IDs and store them */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006555 if ((size_t) (end - p) < 1) {
6556 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
6557 }
Manuel Pégourié-Gonnardc2a7b892019-07-15 09:04:11 +02006558
6559 ssl->transform->in_cid_len = *p++;
6560
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006561 if ((size_t) (end - p) < ssl->transform->in_cid_len + 1u) {
6562 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
6563 }
Manuel Pégourié-Gonnardc2a7b892019-07-15 09:04:11 +02006564
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006565 memcpy(ssl->transform->in_cid, p, ssl->transform->in_cid_len);
Manuel Pégourié-Gonnardc2a7b892019-07-15 09:04:11 +02006566 p += ssl->transform->in_cid_len;
6567
6568 ssl->transform->out_cid_len = *p++;
6569
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006570 if ((size_t) (end - p) < ssl->transform->out_cid_len) {
6571 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
6572 }
Manuel Pégourié-Gonnardc2a7b892019-07-15 09:04:11 +02006573
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006574 memcpy(ssl->transform->out_cid, p, ssl->transform->out_cid_len);
Manuel Pégourié-Gonnardc2a7b892019-07-15 09:04:11 +02006575 p += ssl->transform->out_cid_len;
6576#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
6577
6578 /*
Manuel Pégourié-Gonnardc86c5df2019-07-15 11:23:03 +02006579 * Saved fields from top-level ssl_context structure
6580 */
6581#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006582 if ((size_t) (end - p) < 4) {
6583 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
6584 }
Manuel Pégourié-Gonnardc86c5df2019-07-15 11:23:03 +02006585
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006586 ssl->badmac_seen = ((uint32_t) p[0] << 24) |
6587 ((uint32_t) p[1] << 16) |
6588 ((uint32_t) p[2] << 8) |
6589 ((uint32_t) p[3]);
Manuel Pégourié-Gonnardc86c5df2019-07-15 11:23:03 +02006590 p += 4;
6591#endif /* MBEDTLS_SSL_DTLS_BADMAC_LIMIT */
6592
6593#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006594 if ((size_t) (end - p) < 16) {
6595 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
6596 }
Manuel Pégourié-Gonnardc86c5df2019-07-15 11:23:03 +02006597
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006598 ssl->in_window_top = ((uint64_t) p[0] << 56) |
6599 ((uint64_t) p[1] << 48) |
6600 ((uint64_t) p[2] << 40) |
6601 ((uint64_t) p[3] << 32) |
6602 ((uint64_t) p[4] << 24) |
6603 ((uint64_t) p[5] << 16) |
6604 ((uint64_t) p[6] << 8) |
6605 ((uint64_t) p[7]);
Manuel Pégourié-Gonnardc86c5df2019-07-15 11:23:03 +02006606 p += 8;
6607
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006608 ssl->in_window = ((uint64_t) p[0] << 56) |
6609 ((uint64_t) p[1] << 48) |
6610 ((uint64_t) p[2] << 40) |
6611 ((uint64_t) p[3] << 32) |
6612 ((uint64_t) p[4] << 24) |
6613 ((uint64_t) p[5] << 16) |
6614 ((uint64_t) p[6] << 8) |
6615 ((uint64_t) p[7]);
Manuel Pégourié-Gonnardc86c5df2019-07-15 11:23:03 +02006616 p += 8;
6617#endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */
6618
6619#if defined(MBEDTLS_SSL_PROTO_DTLS)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006620 if ((size_t) (end - p) < 1) {
6621 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
6622 }
Manuel Pégourié-Gonnardc86c5df2019-07-15 11:23:03 +02006623
6624 ssl->disable_datagram_packing = *p++;
6625#endif /* MBEDTLS_SSL_PROTO_DTLS */
6626
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006627 if ((size_t) (end - p) < 8) {
6628 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
6629 }
Manuel Pégourié-Gonnardc86c5df2019-07-15 11:23:03 +02006630
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006631 memcpy(ssl->cur_out_ctr, p, 8);
Manuel Pégourié-Gonnardc86c5df2019-07-15 11:23:03 +02006632 p += 8;
6633
6634#if defined(MBEDTLS_SSL_PROTO_DTLS)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006635 if ((size_t) (end - p) < 2) {
6636 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
6637 }
Manuel Pégourié-Gonnardc86c5df2019-07-15 11:23:03 +02006638
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006639 ssl->mtu = (p[0] << 8) | p[1];
Manuel Pégourié-Gonnardc86c5df2019-07-15 11:23:03 +02006640 p += 2;
6641#endif /* MBEDTLS_SSL_PROTO_DTLS */
6642
6643#if defined(MBEDTLS_SSL_ALPN)
6644 {
6645 uint8_t alpn_len;
6646 const char **cur;
6647
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006648 if ((size_t) (end - p) < 1) {
6649 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
6650 }
Manuel Pégourié-Gonnardc86c5df2019-07-15 11:23:03 +02006651
6652 alpn_len = *p++;
6653
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006654 if (alpn_len != 0 && ssl->conf->alpn_list != NULL) {
Manuel Pégourié-Gonnardc86c5df2019-07-15 11:23:03 +02006655 /* alpn_chosen should point to an item in the configured list */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006656 for (cur = ssl->conf->alpn_list; *cur != NULL; cur++) {
6657 if (strlen(*cur) == alpn_len &&
6658 memcmp(p, cur, alpn_len) == 0) {
Manuel Pégourié-Gonnardc86c5df2019-07-15 11:23:03 +02006659 ssl->alpn_chosen = *cur;
6660 break;
6661 }
6662 }
6663 }
6664
6665 /* can only happen on conf mismatch */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006666 if (alpn_len != 0 && ssl->alpn_chosen == NULL) {
6667 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
6668 }
Manuel Pégourié-Gonnardc86c5df2019-07-15 11:23:03 +02006669
6670 p += alpn_len;
6671 }
6672#endif /* MBEDTLS_SSL_ALPN */
6673
6674 /*
Manuel Pégourié-Gonnard0eb3eac2019-07-15 11:53:51 +02006675 * Forced fields from top-level ssl_context structure
6676 *
6677 * Most of them already set to the correct value by mbedtls_ssl_init() and
6678 * mbedtls_ssl_reset(), so we only need to set the remaining ones.
6679 */
6680 ssl->state = MBEDTLS_SSL_HANDSHAKE_OVER;
6681
6682 ssl->major_ver = MBEDTLS_SSL_MAJOR_VERSION_3;
6683 ssl->minor_ver = MBEDTLS_SSL_MINOR_VERSION_3;
6684
Hanno Becker361b10d2019-08-30 10:42:49 +01006685 /* Adjust pointers for header fields of outgoing records to
6686 * the given transform, accounting for explicit IV and CID. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006687 mbedtls_ssl_update_out_pointers(ssl, ssl->transform);
Hanno Becker361b10d2019-08-30 10:42:49 +01006688
Manuel Pégourié-Gonnard0eb3eac2019-07-15 11:53:51 +02006689#if defined(MBEDTLS_SSL_PROTO_DTLS)
6690 ssl->in_epoch = 1;
6691#endif
6692
6693 /* mbedtls_ssl_reset() leaves the handshake sub-structure allocated,
6694 * which we don't want - otherwise we'd end up freeing the wrong transform
Hanno Beckerce5f5fd2020-02-05 10:47:44 +00006695 * by calling mbedtls_ssl_handshake_wrapup_free_hs_transform()
6696 * inappropriately. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006697 if (ssl->handshake != NULL) {
6698 mbedtls_ssl_handshake_free(ssl);
6699 mbedtls_free(ssl->handshake);
Manuel Pégourié-Gonnard0eb3eac2019-07-15 11:53:51 +02006700 ssl->handshake = NULL;
6701 }
6702
6703 /*
Manuel Pégourié-Gonnard4c90e852019-07-11 10:58:10 +02006704 * Done - should have consumed entire buffer
6705 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006706 if (p != end) {
6707 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
6708 }
Manuel Pégourié-Gonnardac87e282019-05-28 13:02:16 +02006709
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006710 return 0;
Manuel Pégourié-Gonnardac87e282019-05-28 13:02:16 +02006711}
6712
6713/*
Manuel Pégourié-Gonnardb9dfc9f2019-07-12 10:50:19 +02006714 * Deserialize context: public wrapper for error cleaning
Manuel Pégourié-Gonnard4b7e6b92019-07-11 12:50:53 +02006715 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006716int mbedtls_ssl_context_load(mbedtls_ssl_context *context,
6717 const unsigned char *buf,
6718 size_t len)
Manuel Pégourié-Gonnard4b7e6b92019-07-11 12:50:53 +02006719{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006720 int ret = ssl_context_load(context, buf, len);
Manuel Pégourié-Gonnard4b7e6b92019-07-11 12:50:53 +02006721
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006722 if (ret != 0) {
6723 mbedtls_ssl_free(context);
6724 }
Manuel Pégourié-Gonnard4b7e6b92019-07-11 12:50:53 +02006725
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006726 return ret;
Manuel Pégourié-Gonnard4b7e6b92019-07-11 12:50:53 +02006727}
Manuel Pégourié-Gonnard5c0e3772019-07-23 16:13:17 +02006728#endif /* MBEDTLS_SSL_CONTEXT_SERIALIZATION */
Manuel Pégourié-Gonnard4b7e6b92019-07-11 12:50:53 +02006729
6730/*
Paul Bakker5121ce52009-01-03 21:22:43 +00006731 * Free an SSL context
6732 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006733void mbedtls_ssl_free(mbedtls_ssl_context *ssl)
Paul Bakker5121ce52009-01-03 21:22:43 +00006734{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006735 if (ssl == NULL) {
Paul Bakkeraccaffe2014-06-26 13:37:14 +02006736 return;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006737 }
Paul Bakkeraccaffe2014-06-26 13:37:14 +02006738
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006739 MBEDTLS_SSL_DEBUG_MSG(2, ("=> free"));
Paul Bakker5121ce52009-01-03 21:22:43 +00006740
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006741 if (ssl->out_buf != NULL) {
sander-visserb8aa2072020-05-06 22:05:13 +02006742#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
6743 size_t out_buf_len = ssl->out_buf_len;
6744#else
6745 size_t out_buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN;
6746#endif
6747
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006748 mbedtls_platform_zeroize(ssl->out_buf, out_buf_len);
6749 mbedtls_free(ssl->out_buf);
Andrzej Kurek0afa2a12020-03-03 10:39:58 -05006750 ssl->out_buf = NULL;
Paul Bakker5121ce52009-01-03 21:22:43 +00006751 }
6752
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006753 if (ssl->in_buf != NULL) {
sander-visserb8aa2072020-05-06 22:05:13 +02006754#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
6755 size_t in_buf_len = ssl->in_buf_len;
6756#else
6757 size_t in_buf_len = MBEDTLS_SSL_IN_BUFFER_LEN;
6758#endif
6759
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006760 mbedtls_platform_zeroize(ssl->in_buf, in_buf_len);
6761 mbedtls_free(ssl->in_buf);
Andrzej Kurek0afa2a12020-03-03 10:39:58 -05006762 ssl->in_buf = NULL;
Paul Bakker5121ce52009-01-03 21:22:43 +00006763 }
6764
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02006765#if defined(MBEDTLS_ZLIB_SUPPORT)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006766 if (ssl->compress_buf != NULL) {
6767 mbedtls_platform_zeroize(ssl->compress_buf, MBEDTLS_SSL_COMPRESS_BUFFER_LEN);
6768 mbedtls_free(ssl->compress_buf);
Paul Bakker16770332013-10-11 09:59:44 +02006769 }
6770#endif
6771
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006772 if (ssl->transform) {
6773 mbedtls_ssl_transform_free(ssl->transform);
6774 mbedtls_free(ssl->transform);
Paul Bakker48916f92012-09-16 19:57:18 +00006775 }
6776
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006777 if (ssl->handshake) {
6778 mbedtls_ssl_handshake_free(ssl);
6779 mbedtls_ssl_transform_free(ssl->transform_negotiate);
6780 mbedtls_ssl_session_free(ssl->session_negotiate);
Paul Bakker48916f92012-09-16 19:57:18 +00006781
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006782 mbedtls_free(ssl->handshake);
6783 mbedtls_free(ssl->transform_negotiate);
6784 mbedtls_free(ssl->session_negotiate);
Paul Bakker48916f92012-09-16 19:57:18 +00006785 }
6786
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006787 if (ssl->session) {
6788 mbedtls_ssl_session_free(ssl->session);
6789 mbedtls_free(ssl->session);
Paul Bakkerc0463502013-02-14 11:19:38 +01006790 }
6791
Manuel Pégourié-Gonnard55fab2d2015-05-11 16:15:19 +02006792#if defined(MBEDTLS_X509_CRT_PARSE_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006793 if (ssl->hostname != NULL) {
6794 mbedtls_platform_zeroize(ssl->hostname, strlen(ssl->hostname));
6795 mbedtls_free(ssl->hostname);
Paul Bakker5121ce52009-01-03 21:22:43 +00006796 }
Paul Bakker0be444a2013-08-27 21:55:01 +02006797#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00006798
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02006799#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006800 if (mbedtls_ssl_hw_record_finish != NULL) {
6801 MBEDTLS_SSL_DEBUG_MSG(2, ("going for mbedtls_ssl_hw_record_finish()"));
6802 mbedtls_ssl_hw_record_finish(ssl);
Paul Bakker05ef8352012-05-08 09:17:57 +00006803 }
6804#endif
6805
Manuel Pégourié-Gonnarde057d3b2015-05-20 10:59:43 +02006806#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006807 mbedtls_free(ssl->cli_id);
Manuel Pégourié-Gonnard43c02182014-07-22 17:32:01 +02006808#endif
6809
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006810 MBEDTLS_SSL_DEBUG_MSG(2, ("<= free"));
Paul Bakker2da561c2009-02-05 18:00:28 +00006811
Paul Bakker86f04f42013-02-14 11:20:09 +01006812 /* Actually clear after last debug message */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006813 mbedtls_platform_zeroize(ssl, sizeof(mbedtls_ssl_context));
Paul Bakker5121ce52009-01-03 21:22:43 +00006814}
6815
Manuel Pégourié-Gonnardcd523e22015-05-04 13:35:39 +02006816/*
Tom Cosgrove49f99bc2022-12-04 16:44:21 +00006817 * Initialize mbedtls_ssl_config
Manuel Pégourié-Gonnardcd523e22015-05-04 13:35:39 +02006818 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006819void mbedtls_ssl_config_init(mbedtls_ssl_config *conf)
Manuel Pégourié-Gonnardcd523e22015-05-04 13:35:39 +02006820{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006821 memset(conf, 0, sizeof(mbedtls_ssl_config));
Manuel Pégourié-Gonnardcd523e22015-05-04 13:35:39 +02006822}
6823
Gilles Peskineeccd8882020-03-10 12:19:08 +01006824#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
Manuel Pégourié-Gonnard47229c72015-12-04 15:02:56 +01006825static int ssl_preset_default_hashes[] = {
Gilles Peskinec54010c2021-05-12 22:52:09 +02006826#if defined(MBEDTLS_SHA512_C)
Manuel Pégourié-Gonnard47229c72015-12-04 15:02:56 +01006827 MBEDTLS_MD_SHA512,
Gilles Peskinec54010c2021-05-12 22:52:09 +02006828#endif
6829#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384)
Manuel Pégourié-Gonnard47229c72015-12-04 15:02:56 +01006830 MBEDTLS_MD_SHA384,
6831#endif
6832#if defined(MBEDTLS_SHA256_C)
6833 MBEDTLS_MD_SHA256,
6834 MBEDTLS_MD_SHA224,
6835#endif
Gilles Peskine5d2511c2017-05-12 13:16:40 +02006836#if defined(MBEDTLS_SHA1_C) && defined(MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_KEY_EXCHANGE)
Manuel Pégourié-Gonnard47229c72015-12-04 15:02:56 +01006837 MBEDTLS_MD_SHA1,
6838#endif
6839 MBEDTLS_MD_NONE
6840};
Simon Butcherc97b6972015-12-27 23:48:17 +00006841#endif
Manuel Pégourié-Gonnard47229c72015-12-04 15:02:56 +01006842
Manuel Pégourié-Gonnardb31c5f62015-06-17 13:53:47 +02006843static int ssl_preset_suiteb_ciphersuites[] = {
6844 MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
6845 MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
6846 0
6847};
6848
Gilles Peskineeccd8882020-03-10 12:19:08 +01006849#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
Manuel Pégourié-Gonnardb31c5f62015-06-17 13:53:47 +02006850static int ssl_preset_suiteb_hashes[] = {
6851 MBEDTLS_MD_SHA256,
6852 MBEDTLS_MD_SHA384,
6853 MBEDTLS_MD_NONE
6854};
6855#endif
6856
6857#if defined(MBEDTLS_ECP_C)
6858static mbedtls_ecp_group_id ssl_preset_suiteb_curves[] = {
Jaeden Amerod4311042019-06-03 08:27:16 +01006859#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
Manuel Pégourié-Gonnardb31c5f62015-06-17 13:53:47 +02006860 MBEDTLS_ECP_DP_SECP256R1,
Jaeden Amerod4311042019-06-03 08:27:16 +01006861#endif
6862#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
Manuel Pégourié-Gonnardb31c5f62015-06-17 13:53:47 +02006863 MBEDTLS_ECP_DP_SECP384R1,
Jaeden Amerod4311042019-06-03 08:27:16 +01006864#endif
Manuel Pégourié-Gonnardb31c5f62015-06-17 13:53:47 +02006865 MBEDTLS_ECP_DP_NONE
6866};
6867#endif
6868
Manuel Pégourié-Gonnardcd523e22015-05-04 13:35:39 +02006869/*
Tillmann Karras588ad502015-09-25 04:27:22 +02006870 * Load default in mbedtls_ssl_config
Manuel Pégourié-Gonnardcd523e22015-05-04 13:35:39 +02006871 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006872int mbedtls_ssl_config_defaults(mbedtls_ssl_config *conf,
6873 int endpoint, int transport, int preset)
Manuel Pégourié-Gonnardcd523e22015-05-04 13:35:39 +02006874{
Manuel Pégourié-Gonnard8b431fb2015-05-11 12:54:52 +02006875#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_SRV_C)
Janos Follath865b3eb2019-12-16 11:46:15 +00006876 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard8b431fb2015-05-11 12:54:52 +02006877#endif
Manuel Pégourié-Gonnardcd523e22015-05-04 13:35:39 +02006878
Manuel Pégourié-Gonnard0de074f2015-05-14 12:58:01 +02006879 /* Use the functions here so that they are covered in tests,
6880 * but otherwise access member directly for efficiency */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006881 mbedtls_ssl_conf_endpoint(conf, endpoint);
6882 mbedtls_ssl_conf_transport(conf, transport);
Manuel Pégourié-Gonnardcd523e22015-05-04 13:35:39 +02006883
Manuel Pégourié-Gonnardb31c5f62015-06-17 13:53:47 +02006884 /*
6885 * Things that are common to all presets
6886 */
Manuel Pégourié-Gonnard419d5ae2015-05-04 19:32:36 +02006887#if defined(MBEDTLS_SSL_CLI_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006888 if (endpoint == MBEDTLS_SSL_IS_CLIENT) {
Manuel Pégourié-Gonnard419d5ae2015-05-04 19:32:36 +02006889 conf->authmode = MBEDTLS_SSL_VERIFY_REQUIRED;
6890#if defined(MBEDTLS_SSL_SESSION_TICKETS)
6891 conf->session_tickets = MBEDTLS_SSL_SESSION_TICKETS_ENABLED;
6892#endif
6893 }
6894#endif
6895
Manuel Pégourié-Gonnard66dc5552015-05-14 12:28:21 +02006896#if defined(MBEDTLS_ARC4_C)
Manuel Pégourié-Gonnardcd523e22015-05-04 13:35:39 +02006897 conf->arc4_disabled = MBEDTLS_SSL_ARC4_DISABLED;
Manuel Pégourié-Gonnard66dc5552015-05-14 12:28:21 +02006898#endif
Manuel Pégourié-Gonnardcd523e22015-05-04 13:35:39 +02006899
6900#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
6901 conf->encrypt_then_mac = MBEDTLS_SSL_ETM_ENABLED;
6902#endif
6903
6904#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
6905 conf->extended_ms = MBEDTLS_SSL_EXTENDED_MS_ENABLED;
6906#endif
6907
Manuel Pégourié-Gonnard17eab2b2015-05-05 16:34:53 +01006908#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING)
6909 conf->cbc_record_splitting = MBEDTLS_SSL_CBC_RECORD_SPLITTING_ENABLED;
6910#endif
6911
Manuel Pégourié-Gonnarde057d3b2015-05-20 10:59:43 +02006912#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C)
Manuel Pégourié-Gonnardcd523e22015-05-04 13:35:39 +02006913 conf->f_cookie_write = ssl_cookie_write_dummy;
6914 conf->f_cookie_check = ssl_cookie_check_dummy;
6915#endif
6916
6917#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
6918 conf->anti_replay = MBEDTLS_SSL_ANTI_REPLAY_ENABLED;
6919#endif
6920
Janos Follath088ce432017-04-10 12:42:31 +01006921#if defined(MBEDTLS_SSL_SRV_C)
6922 conf->cert_req_ca_list = MBEDTLS_SSL_CERT_REQ_CA_LIST_ENABLED;
6923#endif
6924
Manuel Pégourié-Gonnardcd523e22015-05-04 13:35:39 +02006925#if defined(MBEDTLS_SSL_PROTO_DTLS)
6926 conf->hs_timeout_min = MBEDTLS_SSL_DTLS_TIMEOUT_DFL_MIN;
6927 conf->hs_timeout_max = MBEDTLS_SSL_DTLS_TIMEOUT_DFL_MAX;
6928#endif
6929
6930#if defined(MBEDTLS_SSL_RENEGOTIATION)
6931 conf->renego_max_records = MBEDTLS_SSL_RENEGO_MAX_RECORDS_DEFAULT;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006932 memset(conf->renego_period, 0x00, 2);
6933 memset(conf->renego_period + 2, 0xFF, 6);
Manuel Pégourié-Gonnardcd523e22015-05-04 13:35:39 +02006934#endif
6935
Manuel Pégourié-Gonnardb31c5f62015-06-17 13:53:47 +02006936#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_SRV_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006937 if (endpoint == MBEDTLS_SSL_IS_SERVER) {
6938 const unsigned char dhm_p[] =
6939 MBEDTLS_DHM_RFC3526_MODP_2048_P_BIN;
6940 const unsigned char dhm_g[] =
6941 MBEDTLS_DHM_RFC3526_MODP_2048_G_BIN;
Hanno Becker00d0a682017-10-04 13:14:29 +01006942
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006943 if ((ret = mbedtls_ssl_conf_dh_param_bin(conf,
6944 dhm_p, sizeof(dhm_p),
6945 dhm_g, sizeof(dhm_g))) != 0) {
6946 return ret;
6947 }
6948 }
Manuel Pégourié-Gonnardbd990d62015-06-11 14:49:42 +02006949#endif
6950
Manuel Pégourié-Gonnardb31c5f62015-06-17 13:53:47 +02006951 /*
6952 * Preset-specific defaults
6953 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006954 switch (preset) {
Manuel Pégourié-Gonnardb31c5f62015-06-17 13:53:47 +02006955 /*
6956 * NSA Suite B
6957 */
6958 case MBEDTLS_SSL_PRESET_SUITEB:
6959 conf->min_major_ver = MBEDTLS_SSL_MAJOR_VERSION_3;
6960 conf->min_minor_ver = MBEDTLS_SSL_MINOR_VERSION_3; /* TLS 1.2 */
6961 conf->max_major_ver = MBEDTLS_SSL_MAX_MAJOR_VERSION;
6962 conf->max_minor_ver = MBEDTLS_SSL_MAX_MINOR_VERSION;
6963
6964 conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_0] =
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006965 conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_1] =
6966 conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_2] =
6967 conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_3] =
6968 ssl_preset_suiteb_ciphersuites;
Manuel Pégourié-Gonnardb31c5f62015-06-17 13:53:47 +02006969
6970#if defined(MBEDTLS_X509_CRT_PARSE_C)
6971 conf->cert_profile = &mbedtls_x509_crt_profile_suiteb;
Manuel Pégourié-Gonnardcd523e22015-05-04 13:35:39 +02006972#endif
6973
Gilles Peskineeccd8882020-03-10 12:19:08 +01006974#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
Manuel Pégourié-Gonnardb31c5f62015-06-17 13:53:47 +02006975 conf->sig_hashes = ssl_preset_suiteb_hashes;
6976#endif
6977
6978#if defined(MBEDTLS_ECP_C)
6979 conf->curve_list = ssl_preset_suiteb_curves;
6980#endif
Manuel Pégourié-Gonnardc98204e2015-08-11 04:21:01 +02006981 break;
Manuel Pégourié-Gonnardb31c5f62015-06-17 13:53:47 +02006982
6983 /*
6984 * Default
6985 */
6986 default:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006987 conf->min_major_ver = (MBEDTLS_SSL_MIN_MAJOR_VERSION >
6988 MBEDTLS_SSL_MIN_VALID_MAJOR_VERSION) ?
6989 MBEDTLS_SSL_MIN_MAJOR_VERSION :
6990 MBEDTLS_SSL_MIN_VALID_MAJOR_VERSION;
6991 conf->min_minor_ver = (MBEDTLS_SSL_MIN_MINOR_VERSION >
6992 MBEDTLS_SSL_MIN_VALID_MINOR_VERSION) ?
6993 MBEDTLS_SSL_MIN_MINOR_VERSION :
6994 MBEDTLS_SSL_MIN_VALID_MINOR_VERSION;
Manuel Pégourié-Gonnardb31c5f62015-06-17 13:53:47 +02006995 conf->max_major_ver = MBEDTLS_SSL_MAX_MAJOR_VERSION;
6996 conf->max_minor_ver = MBEDTLS_SSL_MAX_MINOR_VERSION;
6997
6998#if defined(MBEDTLS_SSL_PROTO_DTLS)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01006999 if (transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
Manuel Pégourié-Gonnardb31c5f62015-06-17 13:53:47 +02007000 conf->min_minor_ver = MBEDTLS_SSL_MINOR_VERSION_2;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007001 }
Manuel Pégourié-Gonnardb31c5f62015-06-17 13:53:47 +02007002#endif
7003
7004 conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_0] =
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007005 conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_1] =
7006 conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_2] =
7007 conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_3] =
7008 mbedtls_ssl_list_ciphersuites();
Manuel Pégourié-Gonnardb31c5f62015-06-17 13:53:47 +02007009
7010#if defined(MBEDTLS_X509_CRT_PARSE_C)
7011 conf->cert_profile = &mbedtls_x509_crt_profile_default;
7012#endif
7013
Gilles Peskineeccd8882020-03-10 12:19:08 +01007014#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
Manuel Pégourié-Gonnard47229c72015-12-04 15:02:56 +01007015 conf->sig_hashes = ssl_preset_default_hashes;
Manuel Pégourié-Gonnardb31c5f62015-06-17 13:53:47 +02007016#endif
7017
7018#if defined(MBEDTLS_ECP_C)
7019 conf->curve_list = mbedtls_ecp_grp_id_list();
7020#endif
7021
7022#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_CLI_C)
7023 conf->dhm_min_bitlen = 1024;
7024#endif
7025 }
7026
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007027 return 0;
Manuel Pégourié-Gonnardcd523e22015-05-04 13:35:39 +02007028}
7029
7030/*
7031 * Free mbedtls_ssl_config
7032 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007033void mbedtls_ssl_config_free(mbedtls_ssl_config *conf)
Manuel Pégourié-Gonnardcd523e22015-05-04 13:35:39 +02007034{
7035#if defined(MBEDTLS_DHM_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007036 mbedtls_mpi_free(&conf->dhm_P);
7037 mbedtls_mpi_free(&conf->dhm_G);
Manuel Pégourié-Gonnardcd523e22015-05-04 13:35:39 +02007038#endif
7039
Gilles Peskineeccd8882020-03-10 12:19:08 +01007040#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007041 if (conf->psk != NULL) {
7042 mbedtls_platform_zeroize(conf->psk, conf->psk_len);
7043 mbedtls_free(conf->psk);
Azim Khan27e8a122018-03-21 14:24:11 +00007044 conf->psk = NULL;
Manuel Pégourié-Gonnardcd523e22015-05-04 13:35:39 +02007045 conf->psk_len = 0;
junyeonLEE316b1622017-12-20 16:29:30 +09007046 }
7047
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007048 if (conf->psk_identity != NULL) {
7049 mbedtls_platform_zeroize(conf->psk_identity, conf->psk_identity_len);
7050 mbedtls_free(conf->psk_identity);
Azim Khan27e8a122018-03-21 14:24:11 +00007051 conf->psk_identity = NULL;
Manuel Pégourié-Gonnardcd523e22015-05-04 13:35:39 +02007052 conf->psk_identity_len = 0;
7053 }
7054#endif
7055
7056#if defined(MBEDTLS_X509_CRT_PARSE_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007057 ssl_key_cert_free(conf->key_cert);
Manuel Pégourié-Gonnardcd523e22015-05-04 13:35:39 +02007058#endif
7059
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007060 mbedtls_platform_zeroize(conf, sizeof(mbedtls_ssl_config));
Manuel Pégourié-Gonnardcd523e22015-05-04 13:35:39 +02007061}
7062
Manuel Pégourié-Gonnard5674a972015-10-19 15:14:03 +02007063#if defined(MBEDTLS_PK_C) && \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007064 (defined(MBEDTLS_RSA_C) || defined(MBEDTLS_ECDSA_C))
Manuel Pégourié-Gonnard0d420492013-08-21 16:14:26 +02007065/*
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02007066 * Convert between MBEDTLS_PK_XXX and SSL_SIG_XXX
Manuel Pégourié-Gonnard0d420492013-08-21 16:14:26 +02007067 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007068unsigned char mbedtls_ssl_sig_from_pk(mbedtls_pk_context *pk)
Manuel Pégourié-Gonnard0d420492013-08-21 16:14:26 +02007069{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02007070#if defined(MBEDTLS_RSA_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007071 if (mbedtls_pk_can_do(pk, MBEDTLS_PK_RSA)) {
7072 return MBEDTLS_SSL_SIG_RSA;
7073 }
Manuel Pégourié-Gonnard0d420492013-08-21 16:14:26 +02007074#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02007075#if defined(MBEDTLS_ECDSA_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007076 if (mbedtls_pk_can_do(pk, MBEDTLS_PK_ECDSA)) {
7077 return MBEDTLS_SSL_SIG_ECDSA;
7078 }
Manuel Pégourié-Gonnard0d420492013-08-21 16:14:26 +02007079#endif
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007080 return MBEDTLS_SSL_SIG_ANON;
Manuel Pégourié-Gonnard0d420492013-08-21 16:14:26 +02007081}
7082
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007083unsigned char mbedtls_ssl_sig_from_pk_alg(mbedtls_pk_type_t type)
Hanno Becker7e5437a2017-04-28 17:15:26 +01007084{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007085 switch (type) {
Hanno Becker7e5437a2017-04-28 17:15:26 +01007086 case MBEDTLS_PK_RSA:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007087 return MBEDTLS_SSL_SIG_RSA;
Hanno Becker7e5437a2017-04-28 17:15:26 +01007088 case MBEDTLS_PK_ECDSA:
7089 case MBEDTLS_PK_ECKEY:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007090 return MBEDTLS_SSL_SIG_ECDSA;
Hanno Becker7e5437a2017-04-28 17:15:26 +01007091 default:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007092 return MBEDTLS_SSL_SIG_ANON;
Hanno Becker7e5437a2017-04-28 17:15:26 +01007093 }
7094}
7095
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007096mbedtls_pk_type_t mbedtls_ssl_pk_alg_from_sig(unsigned char sig)
Manuel Pégourié-Gonnarda20c58c2013-08-22 13:52:48 +02007097{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007098 switch (sig) {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02007099#if defined(MBEDTLS_RSA_C)
7100 case MBEDTLS_SSL_SIG_RSA:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007101 return MBEDTLS_PK_RSA;
Manuel Pégourié-Gonnarda20c58c2013-08-22 13:52:48 +02007102#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02007103#if defined(MBEDTLS_ECDSA_C)
7104 case MBEDTLS_SSL_SIG_ECDSA:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007105 return MBEDTLS_PK_ECDSA;
Manuel Pégourié-Gonnarda20c58c2013-08-22 13:52:48 +02007106#endif
7107 default:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007108 return MBEDTLS_PK_NONE;
Manuel Pégourié-Gonnarda20c58c2013-08-22 13:52:48 +02007109 }
7110}
Manuel Pégourié-Gonnard5674a972015-10-19 15:14:03 +02007111#endif /* MBEDTLS_PK_C && ( MBEDTLS_RSA_C || MBEDTLS_ECDSA_C ) */
Manuel Pégourié-Gonnarda20c58c2013-08-22 13:52:48 +02007112
Hanno Becker7e5437a2017-04-28 17:15:26 +01007113#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
Gilles Peskineeccd8882020-03-10 12:19:08 +01007114 defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
Hanno Becker7e5437a2017-04-28 17:15:26 +01007115
7116/* Find an entry in a signature-hash set matching a given hash algorithm. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007117mbedtls_md_type_t mbedtls_ssl_sig_hash_set_find(mbedtls_ssl_sig_hash_set_t *set,
7118 mbedtls_pk_type_t sig_alg)
Hanno Becker7e5437a2017-04-28 17:15:26 +01007119{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007120 switch (sig_alg) {
Hanno Becker7e5437a2017-04-28 17:15:26 +01007121 case MBEDTLS_PK_RSA:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007122 return set->rsa;
Hanno Becker7e5437a2017-04-28 17:15:26 +01007123 case MBEDTLS_PK_ECDSA:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007124 return set->ecdsa;
Hanno Becker7e5437a2017-04-28 17:15:26 +01007125 default:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007126 return MBEDTLS_MD_NONE;
Hanno Becker7e5437a2017-04-28 17:15:26 +01007127 }
7128}
7129
7130/* Add a signature-hash-pair to a signature-hash set */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007131void mbedtls_ssl_sig_hash_set_add(mbedtls_ssl_sig_hash_set_t *set,
7132 mbedtls_pk_type_t sig_alg,
7133 mbedtls_md_type_t md_alg)
Hanno Becker7e5437a2017-04-28 17:15:26 +01007134{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007135 switch (sig_alg) {
Hanno Becker7e5437a2017-04-28 17:15:26 +01007136 case MBEDTLS_PK_RSA:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007137 if (set->rsa == MBEDTLS_MD_NONE) {
Hanno Becker7e5437a2017-04-28 17:15:26 +01007138 set->rsa = md_alg;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007139 }
Hanno Becker7e5437a2017-04-28 17:15:26 +01007140 break;
7141
7142 case MBEDTLS_PK_ECDSA:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007143 if (set->ecdsa == MBEDTLS_MD_NONE) {
Hanno Becker7e5437a2017-04-28 17:15:26 +01007144 set->ecdsa = md_alg;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007145 }
Hanno Becker7e5437a2017-04-28 17:15:26 +01007146 break;
7147
7148 default:
7149 break;
7150 }
7151}
7152
7153/* Allow exactly one hash algorithm for each signature. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007154void mbedtls_ssl_sig_hash_set_const_hash(mbedtls_ssl_sig_hash_set_t *set,
7155 mbedtls_md_type_t md_alg)
Hanno Becker7e5437a2017-04-28 17:15:26 +01007156{
7157 set->rsa = md_alg;
7158 set->ecdsa = md_alg;
7159}
7160
7161#endif /* MBEDTLS_SSL_PROTO_TLS1_2) &&
Gilles Peskineeccd8882020-03-10 12:19:08 +01007162 MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
Hanno Becker7e5437a2017-04-28 17:15:26 +01007163
Manuel Pégourié-Gonnard1a483832013-09-20 12:29:15 +02007164/*
Manuel Pégourié-Gonnard7bfc1222015-06-17 14:34:48 +02007165 * Convert from MBEDTLS_SSL_HASH_XXX to MBEDTLS_MD_XXX
Manuel Pégourié-Gonnard1a483832013-09-20 12:29:15 +02007166 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007167mbedtls_md_type_t mbedtls_ssl_md_alg_from_hash(unsigned char hash)
Manuel Pégourié-Gonnarda20c58c2013-08-22 13:52:48 +02007168{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007169 switch (hash) {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02007170#if defined(MBEDTLS_MD5_C)
7171 case MBEDTLS_SSL_HASH_MD5:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007172 return MBEDTLS_MD_MD5;
Manuel Pégourié-Gonnarda20c58c2013-08-22 13:52:48 +02007173#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02007174#if defined(MBEDTLS_SHA1_C)
7175 case MBEDTLS_SSL_HASH_SHA1:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007176 return MBEDTLS_MD_SHA1;
Manuel Pégourié-Gonnarda20c58c2013-08-22 13:52:48 +02007177#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02007178#if defined(MBEDTLS_SHA256_C)
7179 case MBEDTLS_SSL_HASH_SHA224:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007180 return MBEDTLS_MD_SHA224;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02007181 case MBEDTLS_SSL_HASH_SHA256:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007182 return MBEDTLS_MD_SHA256;
Manuel Pégourié-Gonnarda20c58c2013-08-22 13:52:48 +02007183#endif
Gilles Peskined2d59372021-05-12 22:43:27 +02007184#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02007185 case MBEDTLS_SSL_HASH_SHA384:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007186 return MBEDTLS_MD_SHA384;
Gilles Peskinec54010c2021-05-12 22:52:09 +02007187#endif
7188#if defined(MBEDTLS_SHA512_C)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02007189 case MBEDTLS_SSL_HASH_SHA512:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007190 return MBEDTLS_MD_SHA512;
Manuel Pégourié-Gonnarda20c58c2013-08-22 13:52:48 +02007191#endif
7192 default:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007193 return MBEDTLS_MD_NONE;
Manuel Pégourié-Gonnarda20c58c2013-08-22 13:52:48 +02007194 }
7195}
7196
Manuel Pégourié-Gonnard7bfc1222015-06-17 14:34:48 +02007197/*
7198 * Convert from MBEDTLS_MD_XXX to MBEDTLS_SSL_HASH_XXX
7199 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007200unsigned char mbedtls_ssl_hash_from_md_alg(int md)
Manuel Pégourié-Gonnard7bfc1222015-06-17 14:34:48 +02007201{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007202 switch (md) {
Manuel Pégourié-Gonnard7bfc1222015-06-17 14:34:48 +02007203#if defined(MBEDTLS_MD5_C)
7204 case MBEDTLS_MD_MD5:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007205 return MBEDTLS_SSL_HASH_MD5;
Manuel Pégourié-Gonnard7bfc1222015-06-17 14:34:48 +02007206#endif
7207#if defined(MBEDTLS_SHA1_C)
7208 case MBEDTLS_MD_SHA1:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007209 return MBEDTLS_SSL_HASH_SHA1;
Manuel Pégourié-Gonnard7bfc1222015-06-17 14:34:48 +02007210#endif
7211#if defined(MBEDTLS_SHA256_C)
7212 case MBEDTLS_MD_SHA224:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007213 return MBEDTLS_SSL_HASH_SHA224;
Manuel Pégourié-Gonnard7bfc1222015-06-17 14:34:48 +02007214 case MBEDTLS_MD_SHA256:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007215 return MBEDTLS_SSL_HASH_SHA256;
Manuel Pégourié-Gonnard7bfc1222015-06-17 14:34:48 +02007216#endif
Gilles Peskined2d59372021-05-12 22:43:27 +02007217#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384)
Manuel Pégourié-Gonnard7bfc1222015-06-17 14:34:48 +02007218 case MBEDTLS_MD_SHA384:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007219 return MBEDTLS_SSL_HASH_SHA384;
Gilles Peskinec54010c2021-05-12 22:52:09 +02007220#endif
7221#if defined(MBEDTLS_SHA512_C)
Manuel Pégourié-Gonnard7bfc1222015-06-17 14:34:48 +02007222 case MBEDTLS_MD_SHA512:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007223 return MBEDTLS_SSL_HASH_SHA512;
Manuel Pégourié-Gonnard7bfc1222015-06-17 14:34:48 +02007224#endif
7225 default:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007226 return MBEDTLS_SSL_HASH_NONE;
Manuel Pégourié-Gonnard7bfc1222015-06-17 14:34:48 +02007227 }
7228}
7229
Manuel Pégourié-Gonnardb541da62015-06-17 11:43:30 +02007230#if defined(MBEDTLS_ECP_C)
Manuel Pégourié-Gonnardab240102014-02-04 16:18:07 +01007231/*
Manuel Pégourié-Gonnard7bfc1222015-06-17 14:34:48 +02007232 * Check if a curve proposed by the peer is in our list.
Manuel Pégourié-Gonnard9d412d82015-06-17 12:10:46 +02007233 * Return 0 if we're willing to use it, -1 otherwise.
Manuel Pégourié-Gonnardab240102014-02-04 16:18:07 +01007234 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007235int mbedtls_ssl_check_curve(const mbedtls_ssl_context *ssl, mbedtls_ecp_group_id grp_id)
Manuel Pégourié-Gonnardab240102014-02-04 16:18:07 +01007236{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02007237 const mbedtls_ecp_group_id *gid;
Manuel Pégourié-Gonnardab240102014-02-04 16:18:07 +01007238
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007239 if (ssl->conf->curve_list == NULL) {
7240 return -1;
7241 }
Manuel Pégourié-Gonnard9d412d82015-06-17 12:10:46 +02007242
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007243 for (gid = ssl->conf->curve_list; *gid != MBEDTLS_ECP_DP_NONE; gid++) {
7244 if (*gid == grp_id) {
7245 return 0;
7246 }
7247 }
Manuel Pégourié-Gonnardab240102014-02-04 16:18:07 +01007248
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007249 return -1;
Manuel Pégourié-Gonnardab240102014-02-04 16:18:07 +01007250}
Manuel Pégourié-Gonnard298d6cc2022-02-14 11:34:47 +01007251
7252/*
7253 * Same as mbedtls_ssl_check_curve() but takes a TLS ID for the curve.
7254 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007255int mbedtls_ssl_check_curve_tls_id(const mbedtls_ssl_context *ssl, uint16_t tls_id)
Manuel Pégourié-Gonnard298d6cc2022-02-14 11:34:47 +01007256{
7257 const mbedtls_ecp_curve_info *curve_info =
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007258 mbedtls_ecp_curve_info_from_tls_id(tls_id);
7259 if (curve_info == NULL) {
7260 return -1;
7261 }
7262 return mbedtls_ssl_check_curve(ssl, curve_info->grp_id);
Manuel Pégourié-Gonnard298d6cc2022-02-14 11:34:47 +01007263}
Manuel Pégourié-Gonnardb541da62015-06-17 11:43:30 +02007264#endif /* MBEDTLS_ECP_C */
Manuel Pégourié-Gonnard7f2a07d2014-04-09 09:50:57 +02007265
Gilles Peskineeccd8882020-03-10 12:19:08 +01007266#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
Manuel Pégourié-Gonnard7bfc1222015-06-17 14:34:48 +02007267/*
7268 * Check if a hash proposed by the peer is in our list.
7269 * Return 0 if we're willing to use it, -1 otherwise.
7270 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007271int mbedtls_ssl_check_sig_hash(const mbedtls_ssl_context *ssl,
7272 mbedtls_md_type_t md)
Manuel Pégourié-Gonnard7bfc1222015-06-17 14:34:48 +02007273{
7274 const int *cur;
7275
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007276 if (ssl->conf->sig_hashes == NULL) {
7277 return -1;
7278 }
Manuel Pégourié-Gonnard7bfc1222015-06-17 14:34:48 +02007279
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007280 for (cur = ssl->conf->sig_hashes; *cur != MBEDTLS_MD_NONE; cur++) {
7281 if (*cur == (int) md) {
7282 return 0;
7283 }
7284 }
Manuel Pégourié-Gonnard7bfc1222015-06-17 14:34:48 +02007285
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007286 return -1;
Manuel Pégourié-Gonnard7bfc1222015-06-17 14:34:48 +02007287}
Gilles Peskineeccd8882020-03-10 12:19:08 +01007288#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
Manuel Pégourié-Gonnard7bfc1222015-06-17 14:34:48 +02007289
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02007290#if defined(MBEDTLS_X509_CRT_PARSE_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007291int mbedtls_ssl_check_cert_usage(const mbedtls_x509_crt *cert,
7292 const mbedtls_ssl_ciphersuite_t *ciphersuite,
7293 int cert_endpoint,
7294 uint32_t *flags)
Manuel Pégourié-Gonnard7f2a07d2014-04-09 09:50:57 +02007295{
Manuel Pégourié-Gonnarde6efa6f2015-04-20 11:01:48 +01007296 int ret = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02007297#if defined(MBEDTLS_X509_CHECK_KEY_USAGE)
Manuel Pégourié-Gonnard7f2a07d2014-04-09 09:50:57 +02007298 int usage = 0;
7299#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02007300#if defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE)
Manuel Pégourié-Gonnard0408fd12014-04-11 11:06:22 +02007301 const char *ext_oid;
7302 size_t ext_len;
7303#endif
7304
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02007305#if !defined(MBEDTLS_X509_CHECK_KEY_USAGE) && \
7306 !defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE)
Manuel Pégourié-Gonnard0408fd12014-04-11 11:06:22 +02007307 ((void) cert);
7308 ((void) cert_endpoint);
Manuel Pégourié-Gonnarde6efa6f2015-04-20 11:01:48 +01007309 ((void) flags);
Manuel Pégourié-Gonnard0408fd12014-04-11 11:06:22 +02007310#endif
Manuel Pégourié-Gonnard7f2a07d2014-04-09 09:50:57 +02007311
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02007312#if defined(MBEDTLS_X509_CHECK_KEY_USAGE)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007313 if (cert_endpoint == MBEDTLS_SSL_IS_SERVER) {
Manuel Pégourié-Gonnard7f2a07d2014-04-09 09:50:57 +02007314 /* Server part of the key exchange */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007315 switch (ciphersuite->key_exchange) {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02007316 case MBEDTLS_KEY_EXCHANGE_RSA:
7317 case MBEDTLS_KEY_EXCHANGE_RSA_PSK:
Manuel Pégourié-Gonnarde6028c92015-04-20 12:19:02 +01007318 usage = MBEDTLS_X509_KU_KEY_ENCIPHERMENT;
Manuel Pégourié-Gonnard7f2a07d2014-04-09 09:50:57 +02007319 break;
7320
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02007321 case MBEDTLS_KEY_EXCHANGE_DHE_RSA:
7322 case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA:
7323 case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA:
7324 usage = MBEDTLS_X509_KU_DIGITAL_SIGNATURE;
Manuel Pégourié-Gonnard7f2a07d2014-04-09 09:50:57 +02007325 break;
7326
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02007327 case MBEDTLS_KEY_EXCHANGE_ECDH_RSA:
7328 case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA:
Manuel Pégourié-Gonnarde6028c92015-04-20 12:19:02 +01007329 usage = MBEDTLS_X509_KU_KEY_AGREEMENT;
Manuel Pégourié-Gonnard7f2a07d2014-04-09 09:50:57 +02007330 break;
7331
7332 /* Don't use default: we want warnings when adding new values */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02007333 case MBEDTLS_KEY_EXCHANGE_NONE:
7334 case MBEDTLS_KEY_EXCHANGE_PSK:
7335 case MBEDTLS_KEY_EXCHANGE_DHE_PSK:
7336 case MBEDTLS_KEY_EXCHANGE_ECDHE_PSK:
Manuel Pégourié-Gonnard557535d2015-09-15 17:53:32 +02007337 case MBEDTLS_KEY_EXCHANGE_ECJPAKE:
Manuel Pégourié-Gonnard7f2a07d2014-04-09 09:50:57 +02007338 usage = 0;
7339 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007340 } else {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02007341 /* Client auth: we only implement rsa_sign and mbedtls_ecdsa_sign for now */
7342 usage = MBEDTLS_X509_KU_DIGITAL_SIGNATURE;
Manuel Pégourié-Gonnard7f2a07d2014-04-09 09:50:57 +02007343 }
7344
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007345 if (mbedtls_x509_crt_check_key_usage(cert, usage) != 0) {
Manuel Pégourié-Gonnarde6028c92015-04-20 12:19:02 +01007346 *flags |= MBEDTLS_X509_BADCERT_KEY_USAGE;
Manuel Pégourié-Gonnarde6efa6f2015-04-20 11:01:48 +01007347 ret = -1;
7348 }
Manuel Pégourié-Gonnard0408fd12014-04-11 11:06:22 +02007349#else
7350 ((void) ciphersuite);
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02007351#endif /* MBEDTLS_X509_CHECK_KEY_USAGE */
Manuel Pégourié-Gonnard7f2a07d2014-04-09 09:50:57 +02007352
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02007353#if defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007354 if (cert_endpoint == MBEDTLS_SSL_IS_SERVER) {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02007355 ext_oid = MBEDTLS_OID_SERVER_AUTH;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007356 ext_len = MBEDTLS_OID_SIZE(MBEDTLS_OID_SERVER_AUTH);
7357 } else {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02007358 ext_oid = MBEDTLS_OID_CLIENT_AUTH;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007359 ext_len = MBEDTLS_OID_SIZE(MBEDTLS_OID_CLIENT_AUTH);
Manuel Pégourié-Gonnard0408fd12014-04-11 11:06:22 +02007360 }
7361
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007362 if (mbedtls_x509_crt_check_extended_key_usage(cert, ext_oid, ext_len) != 0) {
Manuel Pégourié-Gonnarde6028c92015-04-20 12:19:02 +01007363 *flags |= MBEDTLS_X509_BADCERT_EXT_KEY_USAGE;
Manuel Pégourié-Gonnarde6efa6f2015-04-20 11:01:48 +01007364 ret = -1;
7365 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02007366#endif /* MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE */
Manuel Pégourié-Gonnard0408fd12014-04-11 11:06:22 +02007367
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007368 return ret;
Manuel Pégourié-Gonnard7f2a07d2014-04-09 09:50:57 +02007369}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02007370#endif /* MBEDTLS_X509_CRT_PARSE_C */
Manuel Pégourié-Gonnard3a306b92014-04-29 15:11:17 +02007371
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007372int mbedtls_ssl_set_calc_verify_md(mbedtls_ssl_context *ssl, int md)
Simon Butcher99000142016-10-13 17:21:01 +01007373{
7374#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007375 if (ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_3) {
Simon Butcher99000142016-10-13 17:21:01 +01007376 return MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007377 }
Simon Butcher99000142016-10-13 17:21:01 +01007378
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007379 switch (md) {
Simon Butcher99000142016-10-13 17:21:01 +01007380#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1)
7381#if defined(MBEDTLS_MD5_C)
7382 case MBEDTLS_SSL_HASH_MD5:
Janos Follath182013f2016-10-25 10:50:22 +01007383 return MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH;
Simon Butcher99000142016-10-13 17:21:01 +01007384#endif
7385#if defined(MBEDTLS_SHA1_C)
7386 case MBEDTLS_SSL_HASH_SHA1:
7387 ssl->handshake->calc_verify = ssl_calc_verify_tls;
7388 break;
7389#endif
7390#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 */
Gilles Peskined2d59372021-05-12 22:43:27 +02007391#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384)
Simon Butcher99000142016-10-13 17:21:01 +01007392 case MBEDTLS_SSL_HASH_SHA384:
7393 ssl->handshake->calc_verify = ssl_calc_verify_tls_sha384;
7394 break;
7395#endif
7396#if defined(MBEDTLS_SHA256_C)
7397 case MBEDTLS_SSL_HASH_SHA256:
7398 ssl->handshake->calc_verify = ssl_calc_verify_tls_sha256;
7399 break;
7400#endif
7401 default:
7402 return MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH;
7403 }
7404
7405 return 0;
7406#else /* !MBEDTLS_SSL_PROTO_TLS1_2 */
7407 (void) ssl;
7408 (void) md;
7409
7410 return MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH;
7411#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
7412}
7413
Andres Amaya Garcia46f5a3e2017-07-20 16:17:51 +01007414#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
7415 defined(MBEDTLS_SSL_PROTO_TLS1_1)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007416int mbedtls_ssl_get_key_exchange_md_ssl_tls(mbedtls_ssl_context *ssl,
7417 unsigned char *output,
7418 unsigned char *data, size_t data_len)
Andres Amaya Garcia46f5a3e2017-07-20 16:17:51 +01007419{
7420 int ret = 0;
7421 mbedtls_md5_context mbedtls_md5;
7422 mbedtls_sha1_context mbedtls_sha1;
7423
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007424 mbedtls_md5_init(&mbedtls_md5);
7425 mbedtls_sha1_init(&mbedtls_sha1);
Andres Amaya Garcia46f5a3e2017-07-20 16:17:51 +01007426
7427 /*
7428 * digitally-signed struct {
7429 * opaque md5_hash[16];
7430 * opaque sha_hash[20];
7431 * };
7432 *
7433 * md5_hash
7434 * MD5(ClientHello.random + ServerHello.random
7435 * + ServerParams);
7436 * sha_hash
7437 * SHA(ClientHello.random + ServerHello.random
7438 * + ServerParams);
7439 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007440 if ((ret = mbedtls_md5_starts_ret(&mbedtls_md5)) != 0) {
7441 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_md5_starts_ret", ret);
Andres Amaya Garcia46f5a3e2017-07-20 16:17:51 +01007442 goto exit;
7443 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007444 if ((ret = mbedtls_md5_update_ret(&mbedtls_md5,
7445 ssl->handshake->randbytes, 64)) != 0) {
7446 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_md5_update_ret", ret);
Andres Amaya Garcia46f5a3e2017-07-20 16:17:51 +01007447 goto exit;
7448 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007449 if ((ret = mbedtls_md5_update_ret(&mbedtls_md5, data, data_len)) != 0) {
7450 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_md5_update_ret", ret);
Andres Amaya Garcia46f5a3e2017-07-20 16:17:51 +01007451 goto exit;
7452 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007453 if ((ret = mbedtls_md5_finish_ret(&mbedtls_md5, output)) != 0) {
7454 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_md5_finish_ret", ret);
Andres Amaya Garcia46f5a3e2017-07-20 16:17:51 +01007455 goto exit;
7456 }
7457
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007458 if ((ret = mbedtls_sha1_starts_ret(&mbedtls_sha1)) != 0) {
7459 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_sha1_starts_ret", ret);
Andres Amaya Garcia46f5a3e2017-07-20 16:17:51 +01007460 goto exit;
7461 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007462 if ((ret = mbedtls_sha1_update_ret(&mbedtls_sha1,
7463 ssl->handshake->randbytes, 64)) != 0) {
7464 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_sha1_update_ret", ret);
Andres Amaya Garcia46f5a3e2017-07-20 16:17:51 +01007465 goto exit;
7466 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007467 if ((ret = mbedtls_sha1_update_ret(&mbedtls_sha1, data,
7468 data_len)) != 0) {
7469 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_sha1_update_ret", ret);
Andres Amaya Garcia46f5a3e2017-07-20 16:17:51 +01007470 goto exit;
7471 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007472 if ((ret = mbedtls_sha1_finish_ret(&mbedtls_sha1,
7473 output + 16)) != 0) {
7474 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_sha1_finish_ret", ret);
Andres Amaya Garcia46f5a3e2017-07-20 16:17:51 +01007475 goto exit;
7476 }
7477
7478exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007479 mbedtls_md5_free(&mbedtls_md5);
7480 mbedtls_sha1_free(&mbedtls_sha1);
Andres Amaya Garcia46f5a3e2017-07-20 16:17:51 +01007481
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007482 if (ret != 0) {
7483 mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
7484 MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR);
7485 }
Andres Amaya Garcia46f5a3e2017-07-20 16:17:51 +01007486
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007487 return ret;
Andres Amaya Garcia46f5a3e2017-07-20 16:17:51 +01007488
7489}
7490#endif /* MBEDTLS_SSL_PROTO_SSL3 || MBEDTLS_SSL_PROTO_TLS1 || \
7491 MBEDTLS_SSL_PROTO_TLS1_1 */
7492
7493#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
7494 defined(MBEDTLS_SSL_PROTO_TLS1_2)
Andrzej Kurekd6db9be2019-01-10 05:27:10 -05007495
7496#if defined(MBEDTLS_USE_PSA_CRYPTO)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007497int mbedtls_ssl_get_key_exchange_md_tls1_2(mbedtls_ssl_context *ssl,
7498 unsigned char *hash, size_t *hashlen,
7499 unsigned char *data, size_t data_len,
7500 mbedtls_md_type_t md_alg)
Andrzej Kurekd6db9be2019-01-10 05:27:10 -05007501{
Andrzej Kurek814feff2019-01-14 04:35:19 -05007502 psa_status_t status;
Jaeden Amero34973232019-02-20 10:32:28 +00007503 psa_hash_operation_t hash_operation = PSA_HASH_OPERATION_INIT;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007504 psa_algorithm_t hash_alg = mbedtls_psa_translate_md(md_alg);
Andrzej Kurekd6db9be2019-01-10 05:27:10 -05007505
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007506 MBEDTLS_SSL_DEBUG_MSG(3, ("Perform PSA-based computation of digest of ServerKeyExchange"));
Andrzej Kurek814feff2019-01-14 04:35:19 -05007507
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007508 if ((status = psa_hash_setup(&hash_operation,
7509 hash_alg)) != PSA_SUCCESS) {
7510 MBEDTLS_SSL_DEBUG_RET(1, "psa_hash_setup", status);
Andrzej Kurekd6db9be2019-01-10 05:27:10 -05007511 goto exit;
7512 }
7513
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007514 if ((status = psa_hash_update(&hash_operation, ssl->handshake->randbytes,
7515 64)) != PSA_SUCCESS) {
7516 MBEDTLS_SSL_DEBUG_RET(1, "psa_hash_update", status);
Andrzej Kurekd6db9be2019-01-10 05:27:10 -05007517 goto exit;
7518 }
7519
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007520 if ((status = psa_hash_update(&hash_operation,
7521 data, data_len)) != PSA_SUCCESS) {
7522 MBEDTLS_SSL_DEBUG_RET(1, "psa_hash_update", status);
Andrzej Kurekd6db9be2019-01-10 05:27:10 -05007523 goto exit;
7524 }
7525
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007526 if ((status = psa_hash_finish(&hash_operation, hash, PSA_HASH_MAX_SIZE,
7527 hashlen)) != PSA_SUCCESS) {
7528 MBEDTLS_SSL_DEBUG_RET(1, "psa_hash_finish", status);
7529 goto exit;
Andrzej Kurekd6db9be2019-01-10 05:27:10 -05007530 }
7531
7532exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007533 if (status != PSA_SUCCESS) {
7534 mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
7535 MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR);
7536 switch (status) {
Andrzej Kurekd6db9be2019-01-10 05:27:10 -05007537 case PSA_ERROR_NOT_SUPPORTED:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007538 return MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE;
Andrzej Kurek814feff2019-01-14 04:35:19 -05007539 case PSA_ERROR_BAD_STATE: /* Intentional fallthrough */
Andrzej Kurekd6db9be2019-01-10 05:27:10 -05007540 case PSA_ERROR_BUFFER_TOO_SMALL:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007541 return MBEDTLS_ERR_MD_BAD_INPUT_DATA;
Andrzej Kurekd6db9be2019-01-10 05:27:10 -05007542 case PSA_ERROR_INSUFFICIENT_MEMORY:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007543 return MBEDTLS_ERR_MD_ALLOC_FAILED;
Andrzej Kurekd6db9be2019-01-10 05:27:10 -05007544 default:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007545 return MBEDTLS_ERR_MD_HW_ACCEL_FAILED;
Andrzej Kurekd6db9be2019-01-10 05:27:10 -05007546 }
7547 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007548 return 0;
Andrzej Kurekd6db9be2019-01-10 05:27:10 -05007549}
7550
7551#else
7552
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007553int mbedtls_ssl_get_key_exchange_md_tls1_2(mbedtls_ssl_context *ssl,
7554 unsigned char *hash, size_t *hashlen,
7555 unsigned char *data, size_t data_len,
7556 mbedtls_md_type_t md_alg)
Andres Amaya Garcia46f5a3e2017-07-20 16:17:51 +01007557{
7558 int ret = 0;
7559 mbedtls_md_context_t ctx;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007560 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(md_alg);
7561 *hashlen = mbedtls_md_get_size(md_info);
Andres Amaya Garcia46f5a3e2017-07-20 16:17:51 +01007562
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007563 MBEDTLS_SSL_DEBUG_MSG(3, ("Perform mbedtls-based computation of digest of ServerKeyExchange"));
Andrzej Kurek814feff2019-01-14 04:35:19 -05007564
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007565 mbedtls_md_init(&ctx);
Andres Amaya Garcia46f5a3e2017-07-20 16:17:51 +01007566
7567 /*
7568 * digitally-signed struct {
7569 * opaque client_random[32];
7570 * opaque server_random[32];
7571 * ServerDHParams params;
7572 * };
7573 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007574 if ((ret = mbedtls_md_setup(&ctx, md_info, 0)) != 0) {
7575 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_md_setup", ret);
Andres Amaya Garcia46f5a3e2017-07-20 16:17:51 +01007576 goto exit;
7577 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007578 if ((ret = mbedtls_md_starts(&ctx)) != 0) {
7579 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_md_starts", ret);
Andres Amaya Garcia46f5a3e2017-07-20 16:17:51 +01007580 goto exit;
7581 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007582 if ((ret = mbedtls_md_update(&ctx, ssl->handshake->randbytes, 64)) != 0) {
7583 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_md_update", ret);
Andres Amaya Garcia46f5a3e2017-07-20 16:17:51 +01007584 goto exit;
7585 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007586 if ((ret = mbedtls_md_update(&ctx, data, data_len)) != 0) {
7587 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_md_update", ret);
Andres Amaya Garcia46f5a3e2017-07-20 16:17:51 +01007588 goto exit;
7589 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007590 if ((ret = mbedtls_md_finish(&ctx, hash)) != 0) {
7591 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_md_finish", ret);
Andres Amaya Garcia46f5a3e2017-07-20 16:17:51 +01007592 goto exit;
7593 }
7594
7595exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007596 mbedtls_md_free(&ctx);
Andres Amaya Garcia46f5a3e2017-07-20 16:17:51 +01007597
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007598 if (ret != 0) {
7599 mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
7600 MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR);
7601 }
Andres Amaya Garcia46f5a3e2017-07-20 16:17:51 +01007602
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01007603 return ret;
Andres Amaya Garcia46f5a3e2017-07-20 16:17:51 +01007604}
Andrzej Kurekd6db9be2019-01-10 05:27:10 -05007605#endif /* MBEDTLS_USE_PSA_CRYPTO */
7606
Andres Amaya Garcia46f5a3e2017-07-20 16:17:51 +01007607#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \
7608 MBEDTLS_SSL_PROTO_TLS1_2 */
7609
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02007610#endif /* MBEDTLS_SSL_TLS_C */