blob: ae7bf10b6f8f8ef07c3ce4a3700ac35ddd8e38bd [file] [log] [blame]
Hanno Beckerbe9d6642020-08-21 13:20:06 +01001/*
2 * TLS 1.3 key schedule
3 *
4 * 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
Hanno Beckerbe9d6642020-08-21 13:20:06 +01006 */
7
Hanno Becker58c5cea2020-09-08 10:31:33 +01008#include "common.h"
Hanno Beckerbe9d6642020-08-21 13:20:06 +01009
10#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
11
12#include "mbedtls/hkdf.h"
Hanno Becker3385a4d2020-08-21 13:03:34 +010013#include "mbedtls/ssl_internal.h"
Hanno Beckerbe9d6642020-08-21 13:20:06 +010014#include "ssl_tls13_keys.h"
Andrzej Kurekdc4a2522022-10-18 09:28:40 -040015#include "psa/crypto_sizes.h"
Hanno Beckerbe9d6642020-08-21 13:20:06 +010016
17#include <stdint.h>
18#include <string.h>
19
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010020#define MBEDTLS_SSL_TLS1_3_LABEL(name, string) \
Hanno Beckere4435ea2020-09-08 10:43:52 +010021 .name = string,
22
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010023#define TLS1_3_EVOLVE_INPUT_SIZE (PSA_HASH_MAX_SIZE > PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE) ? \
24 PSA_HASH_MAX_SIZE : PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE
Andrzej Kurekdc4a2522022-10-18 09:28:40 -040025
Hanno Beckerbe9d6642020-08-21 13:20:06 +010026struct mbedtls_ssl_tls1_3_labels_struct const mbedtls_ssl_tls1_3_labels =
27{
28 /* This seems to work in C, despite the string literal being one
29 * character too long due to the 0-termination. */
Hanno Beckere4435ea2020-09-08 10:43:52 +010030 MBEDTLS_SSL_TLS1_3_LABEL_LIST
Hanno Beckerbe9d6642020-08-21 13:20:06 +010031};
32
Hanno Beckera3a5a4e2020-09-08 11:33:48 +010033#undef MBEDTLS_SSL_TLS1_3_LABEL
Hanno Beckere4435ea2020-09-08 10:43:52 +010034
Hanno Beckerbe9d6642020-08-21 13:20:06 +010035/*
36 * This function creates a HkdfLabel structure used in the TLS 1.3 key schedule.
37 *
38 * The HkdfLabel is specified in RFC 8446 as follows:
39 *
40 * struct HkdfLabel {
41 * uint16 length; // Length of expanded key material
42 * opaque label<7..255>; // Always prefixed by "tls13 "
43 * opaque context<0..255>; // Usually a communication transcript hash
44 * };
45 *
46 * Parameters:
47 * - desired_length: Length of expanded key material
48 * Even though the standard allows expansion to up to
49 * 2**16 Bytes, TLS 1.3 never uses expansion to more than
50 * 255 Bytes, so we require `desired_length` to be at most
51 * 255. This allows us to save a few Bytes of code by
52 * hardcoding the writing of the high bytes.
53 * - (label, llen): label + label length, without "tls13 " prefix
Hanno Becker61baae72020-09-16 09:24:14 +010054 * The label length MUST be less than or equal to
55 * MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_LABEL_LEN
56 * It is the caller's responsibility to ensure this.
Hanno Becker815869a2020-09-08 11:16:16 +010057 * All (label, label length) pairs used in TLS 1.3
58 * can be obtained via MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN().
Hanno Beckerbe9d6642020-08-21 13:20:06 +010059 * - (ctx, clen): context + context length
Hanno Becker61baae72020-09-16 09:24:14 +010060 * The context length MUST be less than or equal to
61 * MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_CONTEXT_LEN
62 * It is the caller's responsibility to ensure this.
Hanno Beckerbe9d6642020-08-21 13:20:06 +010063 * - dst: Target buffer for HkdfLabel structure,
64 * This MUST be a writable buffer of size
65 * at least SSL_TLS1_3_KEY_SCHEDULE_MAX_HKDF_LABEL_LEN Bytes.
66 * - dlen: Pointer at which to store the actual length of
67 * the HkdfLabel structure on success.
68 */
69
Hanno Becker2dfe1322020-09-10 09:23:12 +010070static const char tls1_3_label_prefix[6] = "tls13 ";
71
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010072#define SSL_TLS1_3_KEY_SCHEDULE_HKDF_LABEL_LEN(label_len, context_len) \
73 (2 /* expansion length */ \
74 + 1 /* label length */ \
75 + label_len \
76 + 1 /* context length */ \
77 + context_len)
Hanno Becker9cb0a142020-09-08 10:48:14 +010078
79#define SSL_TLS1_3_KEY_SCHEDULE_MAX_HKDF_LABEL_LEN \
80 SSL_TLS1_3_KEY_SCHEDULE_HKDF_LABEL_LEN( \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010081 sizeof(tls1_3_label_prefix) + \
82 MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_LABEL_LEN, \
83 MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_CONTEXT_LEN)
Hanno Beckerbe9d6642020-08-21 13:20:06 +010084
85static void ssl_tls1_3_hkdf_encode_label(
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010086 size_t desired_length,
87 const unsigned char *label, size_t llen,
88 const unsigned char *ctx, size_t clen,
89 unsigned char *dst, size_t *dlen)
Hanno Beckerbe9d6642020-08-21 13:20:06 +010090{
Hanno Becker2dfe1322020-09-10 09:23:12 +010091 size_t total_label_len =
92 sizeof(tls1_3_label_prefix) + llen;
Hanno Beckerbe9d6642020-08-21 13:20:06 +010093 size_t total_hkdf_lbl_len =
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010094 SSL_TLS1_3_KEY_SCHEDULE_HKDF_LABEL_LEN(total_label_len, clen);
Hanno Beckerbe9d6642020-08-21 13:20:06 +010095
96 unsigned char *p = dst;
97
Hanno Becker531fe302020-09-16 09:45:27 +010098 /* Add the size of the expanded key material.
99 * We're hardcoding the high byte to 0 here assuming that we never use
100 * TLS 1.3 HKDF key expansion to more than 255 Bytes. */
101#if MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_EXPANSION_LEN > 255
102#error "The implementation of ssl_tls1_3_hkdf_encode_label() is not fit for the \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100103 value of MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_EXPANSION_LEN"
Hanno Becker531fe302020-09-16 09:45:27 +0100104#endif
105
Hanno Beckerbe9d6642020-08-21 13:20:06 +0100106 *p++ = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100107 *p++ = MBEDTLS_BYTE_0(desired_length);
Hanno Beckerbe9d6642020-08-21 13:20:06 +0100108
109 /* Add label incl. prefix */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100110 *p++ = MBEDTLS_BYTE_0(total_label_len);
111 memcpy(p, tls1_3_label_prefix, sizeof(tls1_3_label_prefix));
Hanno Becker2dfe1322020-09-10 09:23:12 +0100112 p += sizeof(tls1_3_label_prefix);
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100113 memcpy(p, label, llen);
Hanno Beckerbe9d6642020-08-21 13:20:06 +0100114 p += llen;
115
116 /* Add context value */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100117 *p++ = MBEDTLS_BYTE_0(clen);
118 if (clen != 0) {
119 memcpy(p, ctx, clen);
120 }
Hanno Beckerbe9d6642020-08-21 13:20:06 +0100121
122 /* Return total length to the caller. */
123 *dlen = total_hkdf_lbl_len;
124}
125
126int mbedtls_ssl_tls1_3_hkdf_expand_label(
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100127 mbedtls_md_type_t hash_alg,
128 const unsigned char *secret, size_t slen,
129 const unsigned char *label, size_t llen,
130 const unsigned char *ctx, size_t clen,
131 unsigned char *buf, size_t blen)
Hanno Beckerbe9d6642020-08-21 13:20:06 +0100132{
133 const mbedtls_md_info_t *md;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100134 unsigned char hkdf_label[SSL_TLS1_3_KEY_SCHEDULE_MAX_HKDF_LABEL_LEN];
Hanno Beckerbe9d6642020-08-21 13:20:06 +0100135 size_t hkdf_label_len;
136
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100137 if (llen > MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_LABEL_LEN) {
Hanno Beckerbe9d6642020-08-21 13:20:06 +0100138 /* Should never happen since this is an internal
139 * function, and we know statically which labels
140 * are allowed. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100141 return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
Hanno Beckerbe9d6642020-08-21 13:20:06 +0100142 }
143
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100144 if (clen > MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_CONTEXT_LEN) {
Hanno Beckerbe9d6642020-08-21 13:20:06 +0100145 /* Should not happen, as above. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100146 return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
Hanno Beckerbe9d6642020-08-21 13:20:06 +0100147 }
148
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100149 if (blen > MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_EXPANSION_LEN) {
Hanno Beckerbe9d6642020-08-21 13:20:06 +0100150 /* Should not happen, as above. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100151 return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
Hanno Beckerbe9d6642020-08-21 13:20:06 +0100152 }
153
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100154 md = mbedtls_md_info_from_type(hash_alg);
155 if (md == NULL) {
156 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
157 }
Hanno Beckerbe9d6642020-08-21 13:20:06 +0100158
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100159 ssl_tls1_3_hkdf_encode_label(blen,
160 label, llen,
161 ctx, clen,
162 hkdf_label,
163 &hkdf_label_len);
Hanno Beckerbe9d6642020-08-21 13:20:06 +0100164
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100165 return mbedtls_hkdf_expand(md,
166 secret, slen,
167 hkdf_label, hkdf_label_len,
168 buf, blen);
Hanno Beckerbe9d6642020-08-21 13:20:06 +0100169}
170
Hanno Becker3385a4d2020-08-21 13:03:34 +0100171/*
172 * The traffic keying material is generated from the following inputs:
173 *
174 * - One secret value per sender.
175 * - A purpose value indicating the specific value being generated
176 * - The desired lengths of key and IV.
177 *
178 * The expansion itself is based on HKDF:
179 *
180 * [sender]_write_key = HKDF-Expand-Label( Secret, "key", "", key_length )
181 * [sender]_write_iv = HKDF-Expand-Label( Secret, "iv" , "", iv_length )
182 *
183 * [sender] denotes the sending side and the Secret value is provided
184 * by the function caller. Note that we generate server and client side
185 * keys in a single function call.
186 */
187int mbedtls_ssl_tls1_3_make_traffic_keys(
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100188 mbedtls_md_type_t hash_alg,
189 const unsigned char *client_secret,
190 const unsigned char *server_secret,
191 size_t slen, size_t key_len, size_t iv_len,
192 mbedtls_ssl_key_set *keys)
Hanno Becker3385a4d2020-08-21 13:03:34 +0100193{
194 int ret = 0;
195
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100196 ret = mbedtls_ssl_tls1_3_hkdf_expand_label(hash_alg,
197 client_secret, slen,
198 MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(key),
199 NULL, 0,
200 keys->client_write_key, key_len);
201 if (ret != 0) {
202 return ret;
203 }
Hanno Becker3385a4d2020-08-21 13:03:34 +0100204
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100205 ret = mbedtls_ssl_tls1_3_hkdf_expand_label(hash_alg,
206 server_secret, slen,
207 MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(key),
208 NULL, 0,
209 keys->server_write_key, key_len);
210 if (ret != 0) {
211 return ret;
212 }
Hanno Becker3385a4d2020-08-21 13:03:34 +0100213
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100214 ret = mbedtls_ssl_tls1_3_hkdf_expand_label(hash_alg,
215 client_secret, slen,
216 MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(iv),
217 NULL, 0,
218 keys->client_write_iv, iv_len);
219 if (ret != 0) {
220 return ret;
221 }
Hanno Becker3385a4d2020-08-21 13:03:34 +0100222
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100223 ret = mbedtls_ssl_tls1_3_hkdf_expand_label(hash_alg,
224 server_secret, slen,
225 MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(iv),
226 NULL, 0,
227 keys->server_write_iv, iv_len);
228 if (ret != 0) {
229 return ret;
230 }
Hanno Becker3385a4d2020-08-21 13:03:34 +0100231
Hanno Becker493ea7f2020-09-08 11:01:00 +0100232 keys->key_len = key_len;
233 keys->iv_len = iv_len;
Hanno Becker3385a4d2020-08-21 13:03:34 +0100234
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100235 return 0;
Hanno Becker3385a4d2020-08-21 13:03:34 +0100236}
237
Hanno Beckerb35d5222020-08-21 13:27:44 +0100238int mbedtls_ssl_tls1_3_derive_secret(
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100239 mbedtls_md_type_t hash_alg,
240 const unsigned char *secret, size_t slen,
241 const unsigned char *label, size_t llen,
242 const unsigned char *ctx, size_t clen,
243 int ctx_hashed,
244 unsigned char *dstbuf, size_t buflen)
Hanno Beckerb35d5222020-08-21 13:27:44 +0100245{
246 int ret;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100247 unsigned char hashed_context[MBEDTLS_MD_MAX_SIZE];
Hanno Beckerb35d5222020-08-21 13:27:44 +0100248
249 const mbedtls_md_info_t *md;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100250 md = mbedtls_md_info_from_type(hash_alg);
251 if (md == NULL) {
252 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
Hanno Beckerb35d5222020-08-21 13:27:44 +0100253 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100254
255 if (ctx_hashed == MBEDTLS_SSL_TLS1_3_CONTEXT_UNHASHED) {
256 ret = mbedtls_md(md, ctx, clen, hashed_context);
257 if (ret != 0) {
258 return ret;
259 }
260 clen = mbedtls_md_get_size(md);
261 } else {
262 if (clen > sizeof(hashed_context)) {
Hanno Becker97a21562020-09-09 12:57:16 +0100263 /* This should never happen since this function is internal
Hanno Becker0c42fd92020-09-09 12:58:29 +0100264 * and the code sets `ctx_hashed` correctly.
Hanno Becker97a21562020-09-09 12:57:16 +0100265 * Let's double-check nonetheless to not run at the risk
266 * of getting a stack overflow. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100267 return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
Hanno Becker97a21562020-09-09 12:57:16 +0100268 }
Hanno Beckerb35d5222020-08-21 13:27:44 +0100269
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100270 memcpy(hashed_context, ctx, clen);
Hanno Beckerb35d5222020-08-21 13:27:44 +0100271 }
272
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100273 return mbedtls_ssl_tls1_3_hkdf_expand_label(hash_alg,
274 secret, slen,
275 label, llen,
276 hashed_context, clen,
277 dstbuf, buflen);
Hanno Beckerb35d5222020-08-21 13:27:44 +0100278}
279
Hanno Beckere9cccb42020-08-20 13:42:46 +0100280int mbedtls_ssl_tls1_3_evolve_secret(
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100281 mbedtls_md_type_t hash_alg,
282 const unsigned char *secret_old,
283 const unsigned char *input, size_t input_len,
284 unsigned char *secret_new)
Hanno Beckere9cccb42020-08-20 13:42:46 +0100285{
286 int ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR;
287 size_t hlen, ilen;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100288 unsigned char tmp_secret[PSA_MAC_MAX_SIZE] = { 0 };
289 unsigned char tmp_input[TLS1_3_EVOLVE_INPUT_SIZE] = { 0 };
Hanno Beckere9cccb42020-08-20 13:42:46 +0100290
291 const mbedtls_md_info_t *md;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100292 md = mbedtls_md_info_from_type(hash_alg);
293 if (md == NULL) {
294 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
295 }
Hanno Beckere9cccb42020-08-20 13:42:46 +0100296
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100297 hlen = mbedtls_md_get_size(md);
Hanno Beckere9cccb42020-08-20 13:42:46 +0100298
299 /* For non-initial runs, call Derive-Secret( ., "derived", "")
Hanno Becker61baae72020-09-16 09:24:14 +0100300 * on the old secret. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100301 if (secret_old != NULL) {
Hanno Beckere9cccb42020-08-20 13:42:46 +0100302 ret = mbedtls_ssl_tls1_3_derive_secret(
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100303 hash_alg,
304 secret_old, hlen,
305 MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(derived),
306 NULL, 0, /* context */
307 MBEDTLS_SSL_TLS1_3_CONTEXT_UNHASHED,
308 tmp_secret, hlen);
309 if (ret != 0) {
Hanno Beckere9cccb42020-08-20 13:42:46 +0100310 goto cleanup;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100311 }
Hanno Beckere9cccb42020-08-20 13:42:46 +0100312 }
313
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100314 if (input != NULL) {
315 memcpy(tmp_input, input, input_len);
Hanno Beckere9cccb42020-08-20 13:42:46 +0100316 ilen = input_len;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100317 } else {
Hanno Beckere9cccb42020-08-20 13:42:46 +0100318 ilen = hlen;
319 }
320
321 /* HKDF-Extract takes a salt and input key material.
322 * The salt is the old secret, and the input key material
323 * is the input secret (PSK / ECDHE). */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100324 ret = mbedtls_hkdf_extract(md,
325 tmp_secret, hlen,
326 tmp_input, ilen,
327 secret_new);
328 if (ret != 0) {
Hanno Beckere9cccb42020-08-20 13:42:46 +0100329 goto cleanup;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100330 }
Hanno Beckere9cccb42020-08-20 13:42:46 +0100331
332 ret = 0;
333
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100334cleanup:
Hanno Beckere9cccb42020-08-20 13:42:46 +0100335
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100336 mbedtls_platform_zeroize(tmp_secret, sizeof(tmp_secret));
337 mbedtls_platform_zeroize(tmp_input, sizeof(tmp_input));
338 return ret;
Hanno Beckere9cccb42020-08-20 13:42:46 +0100339}
340
Hanno Beckerbe9d6642020-08-21 13:20:06 +0100341#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */