1 /*
2 * Copyright 2016-2025 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License 2.0 (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
8 */
9
10 #include <openssl/ssl.h>
11 #include <openssl/evp.h>
12
13 #include "../ssl/ssl_local.h"
14 #include "internal/ssl_unwrap.h"
15 #include "testutil.h"
16
17 #define IVLEN 12
18 #define KEYLEN 16
19
20 /*
21 * Based on the test vectors available in:
22 * https://tools.ietf.org/html/draft-ietf-tls-tls13-vectors-06
23 */
24
25 static unsigned char hs_start_hash[] = {
26 0xc6, 0xc9, 0x18, 0xad, 0x2f, 0x41, 0x99, 0xd5, 0x59, 0x8e, 0xaf, 0x01, 0x16,
27 0xcb, 0x7a, 0x5c, 0x2c, 0x14, 0xcb, 0x54, 0x78, 0x12, 0x18, 0x88, 0x8d, 0xb7,
28 0x03, 0x0d, 0xd5, 0x0d, 0x5e, 0x6d
29 };
30
31 static unsigned char hs_full_hash[] = {
32 0xf8, 0xc1, 0x9e, 0x8c, 0x77, 0xc0, 0x38, 0x79, 0xbb, 0xc8, 0xeb, 0x6d, 0x56,
33 0xe0, 0x0d, 0xd5, 0xd8, 0x6e, 0xf5, 0x59, 0x27, 0xee, 0xfc, 0x08, 0xe1, 0xb0,
34 0x02, 0xb6, 0xec, 0xe0, 0x5d, 0xbf
35 };
36
37 static unsigned char early_secret[] = {
38 0x33, 0xad, 0x0a, 0x1c, 0x60, 0x7e, 0xc0, 0x3b, 0x09, 0xe6, 0xcd, 0x98, 0x93,
39 0x68, 0x0c, 0xe2, 0x10, 0xad, 0xf3, 0x00, 0xaa, 0x1f, 0x26, 0x60, 0xe1, 0xb2,
40 0x2e, 0x10, 0xf1, 0x70, 0xf9, 0x2a
41 };
42
43 static unsigned char ecdhe_secret[] = {
44 0x81, 0x51, 0xd1, 0x46, 0x4c, 0x1b, 0x55, 0x53, 0x36, 0x23, 0xb9, 0xc2, 0x24,
45 0x6a, 0x6a, 0x0e, 0x6e, 0x7e, 0x18, 0x50, 0x63, 0xe1, 0x4a, 0xfd, 0xaf, 0xf0,
46 0xb6, 0xe1, 0xc6, 0x1a, 0x86, 0x42
47 };
48
49 static unsigned char handshake_secret[] = {
50 0x5b, 0x4f, 0x96, 0x5d, 0xf0, 0x3c, 0x68, 0x2c, 0x46, 0xe6, 0xee, 0x86, 0xc3,
51 0x11, 0x63, 0x66, 0x15, 0xa1, 0xd2, 0xbb, 0xb2, 0x43, 0x45, 0xc2, 0x52, 0x05,
52 0x95, 0x3c, 0x87, 0x9e, 0x8d, 0x06
53 };
54
55 static const char *client_hts_label = "c hs traffic";
56
57 static unsigned char client_hts[] = {
58 0xe2, 0xe2, 0x32, 0x07, 0xbd, 0x93, 0xfb, 0x7f, 0xe4, 0xfc, 0x2e, 0x29, 0x7a,
59 0xfe, 0xab, 0x16, 0x0e, 0x52, 0x2b, 0x5a, 0xb7, 0x5d, 0x64, 0xa8, 0x6e, 0x75,
60 0xbc, 0xac, 0x3f, 0x3e, 0x51, 0x03
61 };
62
63 static unsigned char client_hts_key[] = {
64 0x26, 0x79, 0xa4, 0x3e, 0x1d, 0x76, 0x78, 0x40, 0x34, 0xea, 0x17, 0x97, 0xd5,
65 0xad, 0x26, 0x49
66 };
67
68 static unsigned char client_hts_iv[] = {
69 0x54, 0x82, 0x40, 0x52, 0x90, 0xdd, 0x0d, 0x2f, 0x81, 0xc0, 0xd9, 0x42
70 };
71
72 static const char *server_hts_label = "s hs traffic";
73
74 static unsigned char server_hts[] = {
75 0x3b, 0x7a, 0x83, 0x9c, 0x23, 0x9e, 0xf2, 0xbf, 0x0b, 0x73, 0x05, 0xa0, 0xe0,
76 0xc4, 0xe5, 0xa8, 0xc6, 0xc6, 0x93, 0x30, 0xa7, 0x53, 0xb3, 0x08, 0xf5, 0xe3,
77 0xa8, 0x3a, 0xa2, 0xef, 0x69, 0x79
78 };
79
80 static unsigned char server_hts_key[] = {
81 0xc6, 0x6c, 0xb1, 0xae, 0xc5, 0x19, 0xdf, 0x44, 0xc9, 0x1e, 0x10, 0x99, 0x55,
82 0x11, 0xac, 0x8b
83 };
84
85 static unsigned char server_hts_iv[] = {
86 0xf7, 0xf6, 0x88, 0x4c, 0x49, 0x81, 0x71, 0x6c, 0x2d, 0x0d, 0x29, 0xa4
87 };
88
89 static unsigned char master_secret[] = {
90 0x5c, 0x79, 0xd1, 0x69, 0x42, 0x4e, 0x26, 0x2b, 0x56, 0x32, 0x03, 0x62, 0x7b,
91 0xe4, 0xeb, 0x51, 0x03, 0x3f, 0x58, 0x8c, 0x43, 0xc9, 0xce, 0x03, 0x73, 0x37,
92 0x2d, 0xbc, 0xbc, 0x01, 0x85, 0xa7
93 };
94
95 static const char *client_ats_label = "c ap traffic";
96
97 static unsigned char client_ats[] = {
98 0xe2, 0xf0, 0xdb, 0x6a, 0x82, 0xe8, 0x82, 0x80, 0xfc, 0x26, 0xf7, 0x3c, 0x89,
99 0x85, 0x4e, 0xe8, 0x61, 0x5e, 0x25, 0xdf, 0x28, 0xb2, 0x20, 0x79, 0x62, 0xfa,
100 0x78, 0x22, 0x26, 0xb2, 0x36, 0x26
101 };
102
103 static unsigned char client_ats_key[] = {
104 0x88, 0xb9, 0x6a, 0xd6, 0x86, 0xc8, 0x4b, 0xe5, 0x5a, 0xce, 0x18, 0xa5, 0x9c,
105 0xce, 0x5c, 0x87
106 };
107
108 static unsigned char client_ats_iv[] = {
109 0xb9, 0x9d, 0xc5, 0x8c, 0xd5, 0xff, 0x5a, 0xb0, 0x82, 0xfd, 0xad, 0x19
110 };
111
112 static const char *server_ats_label = "s ap traffic";
113
114 static unsigned char server_ats[] = {
115 0x5b, 0x73, 0xb1, 0x08, 0xd9, 0xac, 0x1b, 0x9b, 0x0c, 0x82, 0x48, 0xca, 0x39,
116 0x26, 0xec, 0x6e, 0x7b, 0xc4, 0x7e, 0x41, 0x17, 0x06, 0x96, 0x39, 0x87, 0xec,
117 0x11, 0x43, 0x5d, 0x30, 0x57, 0x19
118 };
119
120 static unsigned char server_ats_key[] = {
121 0xa6, 0x88, 0xeb, 0xb5, 0xac, 0x82, 0x6d, 0x6f, 0x42, 0xd4, 0x5c, 0x0c, 0xc4,
122 0x4b, 0x9b, 0x7d
123 };
124
125 static unsigned char server_ats_iv[] = {
126 0xc1, 0xca, 0xd4, 0x42, 0x5a, 0x43, 0x8b, 0x5d, 0xe7, 0x14, 0x83, 0x0a
127 };
128
129 /* Mocked out implementations of various functions */
ssl3_digest_cached_records(SSL_CONNECTION * s,int keep)130 int ssl3_digest_cached_records(SSL_CONNECTION *s, int keep)
131 {
132 return 1;
133 }
134
135 static int full_hash = 0;
136
137 /* Give a hash of the currently set handshake */
ssl_handshake_hash(SSL_CONNECTION * s,unsigned char * out,size_t outlen,size_t * hashlen)138 int ssl_handshake_hash(SSL_CONNECTION *s, unsigned char *out, size_t outlen,
139 size_t *hashlen)
140 {
141 if (sizeof(hs_start_hash) > outlen
142 || sizeof(hs_full_hash) != sizeof(hs_start_hash))
143 return 0;
144
145 if (full_hash) {
146 memcpy(out, hs_full_hash, sizeof(hs_full_hash));
147 *hashlen = sizeof(hs_full_hash);
148 } else {
149 memcpy(out, hs_start_hash, sizeof(hs_start_hash));
150 *hashlen = sizeof(hs_start_hash);
151 }
152
153 return 1;
154 }
155
ssl_handshake_md(SSL_CONNECTION * s)156 const EVP_MD *ssl_handshake_md(SSL_CONNECTION *s)
157 {
158 return EVP_sha256();
159 }
160
ssl_cipher_get_evp_cipher(SSL_CTX * ctx,const SSL_CIPHER * sslc,const EVP_CIPHER ** enc)161 int ssl_cipher_get_evp_cipher(SSL_CTX *ctx, const SSL_CIPHER *sslc,
162 const EVP_CIPHER **enc)
163 {
164 return 0;
165 }
166
ssl_cipher_get_evp_md_mac(SSL_CTX * ctx,const SSL_CIPHER * sslc,const EVP_MD ** md,int * mac_pkey_type,size_t * mac_secret_size)167 int ssl_cipher_get_evp_md_mac(SSL_CTX *ctx, const SSL_CIPHER *sslc,
168 const EVP_MD **md,
169 int *mac_pkey_type, size_t *mac_secret_size)
170 {
171 return 0;
172 }
173
ssl_cipher_get_evp(SSL_CTX * ctx,const SSL_SESSION * s,const EVP_CIPHER ** enc,const EVP_MD ** md,int * mac_pkey_type,size_t * mac_secret_size,SSL_COMP ** comp,int use_etm)174 int ssl_cipher_get_evp(SSL_CTX *ctx, const SSL_SESSION *s,
175 const EVP_CIPHER **enc, const EVP_MD **md,
176 int *mac_pkey_type, size_t *mac_secret_size,
177 SSL_COMP **comp, int use_etm)
178
179 {
180 return 0;
181 }
182
tls1_alert_code(int code)183 int tls1_alert_code(int code)
184 {
185 return code;
186 }
187
ssl_log_secret(SSL_CONNECTION * sc,const char * label,const uint8_t * secret,size_t secret_len)188 int ssl_log_secret(SSL_CONNECTION *sc,
189 const char *label,
190 const uint8_t *secret,
191 size_t secret_len)
192 {
193 return 1;
194 }
195
ssl_md(SSL_CTX * ctx,int idx)196 const EVP_MD *ssl_md(SSL_CTX *ctx, int idx)
197 {
198 return EVP_sha256();
199 }
200
ossl_statem_send_fatal(SSL_CONNECTION * s,int al)201 void ossl_statem_send_fatal(SSL_CONNECTION *s, int al)
202 {
203 }
204
ossl_statem_fatal(SSL_CONNECTION * s,int al,int reason,const char * fmt,...)205 void ossl_statem_fatal(SSL_CONNECTION *s, int al, int reason,
206 const char *fmt, ...)
207 {
208 }
209
ossl_statem_export_allowed(SSL_CONNECTION * s)210 int ossl_statem_export_allowed(SSL_CONNECTION *s)
211 {
212 return 1;
213 }
214
ossl_statem_export_early_allowed(SSL_CONNECTION * s)215 int ossl_statem_export_early_allowed(SSL_CONNECTION *s)
216 {
217 return 1;
218 }
219
ssl_evp_cipher_free(const EVP_CIPHER * cipher)220 void ssl_evp_cipher_free(const EVP_CIPHER *cipher)
221 {
222 }
223
ssl_evp_md_free(const EVP_MD * md)224 void ssl_evp_md_free(const EVP_MD *md)
225 {
226 }
227
ssl_set_new_record_layer(SSL_CONNECTION * s,int version,int direction,int level,unsigned char * secret,size_t secretlen,unsigned char * key,size_t keylen,unsigned char * iv,size_t ivlen,unsigned char * mackey,size_t mackeylen,const EVP_CIPHER * ciph,size_t taglen,int mactype,const EVP_MD * md,const SSL_COMP * comp,const EVP_MD * kdfdigest)228 int ssl_set_new_record_layer(SSL_CONNECTION *s, int version, int direction,
229 int level, unsigned char *secret, size_t secretlen,
230 unsigned char *key, size_t keylen,
231 unsigned char *iv, size_t ivlen,
232 unsigned char *mackey, size_t mackeylen,
233 const EVP_CIPHER *ciph, size_t taglen,
234 int mactype, const EVP_MD *md,
235 const SSL_COMP *comp, const EVP_MD *kdfdigest)
236 {
237 return 0;
238 }
239
240 /* End of mocked out code */
241
test_secret(SSL_CONNECTION * s,unsigned char * prk,const unsigned char * label,size_t labellen,const unsigned char * ref_secret,const unsigned char * ref_key,const unsigned char * ref_iv)242 static int test_secret(SSL_CONNECTION *s, unsigned char *prk,
243 const unsigned char *label, size_t labellen,
244 const unsigned char *ref_secret,
245 const unsigned char *ref_key, const unsigned char *ref_iv)
246 {
247 size_t hashsize;
248 unsigned char gensecret[EVP_MAX_MD_SIZE];
249 unsigned char hash[EVP_MAX_MD_SIZE];
250 unsigned char key[KEYLEN];
251 unsigned char iv[IVLEN];
252 const EVP_MD *md = ssl_handshake_md(s);
253
254 if (!ssl_handshake_hash(s, hash, sizeof(hash), &hashsize)) {
255 TEST_error("Failed to get hash");
256 return 0;
257 }
258
259 if (!tls13_hkdf_expand(s, md, prk, label, labellen, hash, hashsize,
260 gensecret, hashsize, 1)) {
261 TEST_error("Secret generation failed");
262 return 0;
263 }
264
265 if (!TEST_mem_eq(gensecret, hashsize, ref_secret, hashsize))
266 return 0;
267
268 if (!tls13_derive_key(s, md, gensecret, key, KEYLEN)) {
269 TEST_error("Key generation failed");
270 return 0;
271 }
272
273 if (!TEST_mem_eq(key, KEYLEN, ref_key, KEYLEN))
274 return 0;
275
276 if (!tls13_derive_iv(s, md, gensecret, iv, IVLEN)) {
277 TEST_error("IV generation failed");
278 return 0;
279 }
280
281 if (!TEST_mem_eq(iv, IVLEN, ref_iv, IVLEN))
282 return 0;
283
284 return 1;
285 }
286
test_handshake_secrets(void)287 static int test_handshake_secrets(void)
288 {
289 SSL_CTX *ctx = NULL;
290 SSL *ssl = NULL;
291 SSL_CONNECTION *s;
292 int ret = 0;
293 size_t hashsize;
294 unsigned char out_master_secret[EVP_MAX_MD_SIZE];
295 size_t master_secret_length;
296
297 ctx = SSL_CTX_new(TLS_method());
298 if (!TEST_ptr(ctx))
299 goto err;
300
301 ssl = SSL_new(ctx);
302 if (!TEST_ptr(ssl) || !TEST_ptr(s = SSL_CONNECTION_FROM_SSL_ONLY(ssl)))
303 goto err;
304
305 s->session = SSL_SESSION_new();
306 if (!TEST_ptr(s->session))
307 goto err;
308
309 if (!TEST_true(tls13_generate_secret(s, ssl_handshake_md(s), NULL, NULL, 0,
310 (unsigned char *)&s->early_secret))) {
311 TEST_info("Early secret generation failed");
312 goto err;
313 }
314
315 if (!TEST_mem_eq(s->early_secret, sizeof(early_secret),
316 early_secret, sizeof(early_secret))) {
317 TEST_info("Early secret does not match");
318 goto err;
319 }
320
321 if (!TEST_true(tls13_generate_handshake_secret(s, ecdhe_secret,
322 sizeof(ecdhe_secret)))) {
323 TEST_info("Handshake secret generation failed");
324 goto err;
325 }
326
327 if (!TEST_mem_eq(s->handshake_secret, sizeof(handshake_secret),
328 handshake_secret, sizeof(handshake_secret)))
329 goto err;
330
331 hashsize = EVP_MD_get_size(ssl_handshake_md(s));
332 if (!TEST_size_t_eq(sizeof(client_hts), hashsize))
333 goto err;
334 if (!TEST_size_t_eq(sizeof(client_hts_key), KEYLEN))
335 goto err;
336 if (!TEST_size_t_eq(sizeof(client_hts_iv), IVLEN))
337 goto err;
338
339 if (!TEST_true(test_secret(s, s->handshake_secret,
340 (unsigned char *)client_hts_label,
341 strlen(client_hts_label), client_hts,
342 client_hts_key, client_hts_iv))) {
343 TEST_info("Client handshake secret test failed");
344 goto err;
345 }
346
347 if (!TEST_size_t_eq(sizeof(server_hts), hashsize))
348 goto err;
349 if (!TEST_size_t_eq(sizeof(server_hts_key), KEYLEN))
350 goto err;
351 if (!TEST_size_t_eq(sizeof(server_hts_iv), IVLEN))
352 goto err;
353
354 if (!TEST_true(test_secret(s, s->handshake_secret,
355 (unsigned char *)server_hts_label,
356 strlen(server_hts_label), server_hts,
357 server_hts_key, server_hts_iv))) {
358 TEST_info("Server handshake secret test failed");
359 goto err;
360 }
361
362 /*
363 * Ensure the mocked out ssl_handshake_hash() returns the full handshake
364 * hash.
365 */
366 full_hash = 1;
367
368 if (!TEST_true(tls13_generate_master_secret(s, out_master_secret,
369 s->handshake_secret, hashsize,
370 &master_secret_length))) {
371 TEST_info("Master secret generation failed");
372 goto err;
373 }
374
375 if (!TEST_mem_eq(out_master_secret, master_secret_length,
376 master_secret, sizeof(master_secret))) {
377 TEST_info("Master secret does not match");
378 goto err;
379 }
380
381 if (!TEST_size_t_eq(sizeof(client_ats), hashsize))
382 goto err;
383 if (!TEST_size_t_eq(sizeof(client_ats_key), KEYLEN))
384 goto err;
385 if (!TEST_size_t_eq(sizeof(client_ats_iv), IVLEN))
386 goto err;
387
388 if (!TEST_true(test_secret(s, out_master_secret,
389 (unsigned char *)client_ats_label,
390 strlen(client_ats_label), client_ats,
391 client_ats_key, client_ats_iv))) {
392 TEST_info("Client application data secret test failed");
393 goto err;
394 }
395
396 if (!TEST_size_t_eq(sizeof(server_ats), hashsize))
397 goto err;
398 if (!TEST_size_t_eq(sizeof(server_ats_key), KEYLEN))
399 goto err;
400 if (!TEST_size_t_eq(sizeof(server_ats_iv), IVLEN))
401 goto err;
402
403 if (!TEST_true(test_secret(s, out_master_secret,
404 (unsigned char *)server_ats_label,
405 strlen(server_ats_label), server_ats,
406 server_ats_key, server_ats_iv))) {
407 TEST_info("Server application data secret test failed");
408 goto err;
409 }
410
411 ret = 1;
412 err:
413 SSL_free(ssl);
414 SSL_CTX_free(ctx);
415 return ret;
416 }
417
setup_tests(void)418 int setup_tests(void)
419 {
420 ADD_TEST(test_handshake_secrets);
421 return 1;
422 }
423