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