xref: /freebsd/crypto/openssl/test/tls13secretstest.c (revision e7be843b4a162e68651d3911f0357ed464915629)
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