Update state machine to be closer to TLS1.3
[openssl.git] / test / tls13secretstest.c
1 /*
2  * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the OpenSSL license (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 #include "../ssl/ssl_locl.h"
13
14 #include "testutil.h"
15
16 #define IVLEN   12
17 #define KEYLEN  16
18
19 /* The following are unofficial test vectors generated from a locally modified
20  * version of picotls.
21  * TODO(TLS1.3): As and when official vectors become available we should use
22  * those, e.g. see
23  * https://www.ietf.org/id/draft-thomson-tls-tls13-vectors-00.txt, however at
24  * the time of writing these are not suitable because they are based on
25  * draft -16, which works slightly differently to the draft -18 vectors below.
26  */
27
28 static unsigned char hs_start_hash[] = {
29 0xec, 0x14, 0x7a, 0x06, 0xde, 0xa3, 0xc8, 0x84, 0x6c, 0x02, 0xb2, 0x23, 0x8e,
30 0x41, 0xbd, 0xdc, 0x9d, 0x89, 0xf9, 0xae, 0xa1, 0x7b, 0x5e, 0xfd, 0x4d, 0x74,
31 0x82, 0xaf, 0x75, 0x88, 0x1c, 0x0a
32 };
33
34 static unsigned char hs_full_hash[] = {
35 0x75, 0x1a, 0x3d, 0x4a, 0x14, 0xdf, 0xab, 0xeb, 0x68, 0xe9, 0x2c, 0xa5, 0x91,
36 0x8e, 0x24, 0x08, 0xb9, 0xbc, 0xb0, 0x74, 0x89, 0x82, 0xec, 0x9c, 0x32, 0x30,
37 0xac, 0x30, 0xbb, 0xeb, 0x23, 0xe2,
38 };
39
40 static unsigned char early_secret[] = {
41 0x33, 0xad, 0x0a, 0x1c, 0x60, 0x7e, 0xc0, 0x3b, 0x09, 0xe6, 0xcd, 0x98, 0x93,
42 0x68, 0x0c, 0xe2, 0x10, 0xad, 0xf3, 0x00, 0xaa, 0x1f, 0x26, 0x60, 0xe1, 0xb2,
43 0x2e, 0x10, 0xf1, 0x70, 0xf9, 0x2a
44 };
45
46 static unsigned char ecdhe_secret[] = {
47 0xe7, 0xb8, 0xfe, 0xf8, 0x90, 0x3b, 0x52, 0x0c, 0xb9, 0xa1, 0x89, 0x71, 0xb6,
48 0x9d, 0xd4, 0x5d, 0xca, 0x53, 0xce, 0x2f, 0x12, 0xbf, 0x3b, 0xef, 0x93, 0x15,
49 0xe3, 0x12, 0x71, 0xdf, 0x4b, 0x40
50 };
51
52 static unsigned char handshake_secret[] = {
53 0xdf, 0xc9, 0x41, 0xd8, 0x26, 0x93, 0x2a, 0x59, 0x11, 0xb3, 0xb7, 0xd0, 0x38,
54 0xcb, 0x65, 0x6f, 0xda, 0xaf, 0x77, 0x07, 0x1e, 0x40, 0x9a, 0x9b, 0xa6, 0xca,
55 0x74, 0xda, 0x17, 0xb4, 0xe0, 0x04,
56 };
57
58 static const char *client_hts_label = "client handshake traffic secret";
59
60 static unsigned char client_hts[] = {
61 0x4b, 0x38, 0x48, 0xf1, 0x5d, 0xb1, 0x5e, 0x88, 0xcf, 0x3e, 0x3b, 0xff, 0xa6,
62 0xba, 0x02, 0xc1, 0xc5, 0xd1, 0xe5, 0xb1, 0xc3, 0xf3, 0x10, 0xdf, 0xe5, 0xc9,
63 0x69, 0x5a, 0x4a, 0xc6, 0x06, 0x38,
64 };
65
66 static unsigned char client_hts_key[] = {
67 0xe5, 0x7b, 0x8c, 0x38, 0x6d, 0x6f, 0x09, 0x14, 0xe2, 0xe5, 0x4e, 0x36, 0x23,
68 0x91, 0x2a, 0xd4
69 };
70
71 static unsigned char client_hts_iv[] = {
72 0x4d, 0x2e, 0x61, 0x0c, 0x4d, 0x3a, 0x8e, 0x5f, 0x15, 0x41, 0x1e, 0xfd
73 };
74
75 static const char *server_hts_label = "server handshake traffic secret";
76
77 static unsigned char server_hts[] = {
78 0x74, 0x1f, 0xb3, 0xb8, 0x41, 0x24, 0xc4, 0x7e, 0x1b, 0x2e, 0xa9, 0x4f, 0x0c,
79 0x42, 0xc9, 0x06, 0xb7, 0x7c, 0x84, 0x92, 0x05, 0xed, 0x5f, 0x19, 0xda, 0xbb,
80 0xbb, 0xce, 0xc7, 0x29, 0x06, 0x7e,
81 };
82
83 static unsigned char server_hts_key[] = {
84 0x72, 0x61, 0x1c, 0xc8, 0x0d, 0x65, 0x9c, 0x89, 0xf8, 0x94, 0x9e, 0x32, 0x67,
85 0xe1, 0x6c, 0x2d
86
87 };
88
89 static unsigned char server_hts_iv[] = {
90 0x43, 0xfe, 0x11, 0x29, 0x0f, 0xe8, 0xfe, 0x84, 0x9c, 0x9b, 0x21, 0xef,
91 };
92
93 static unsigned char master_secret[] = {
94 0xfe, 0x8d, 0xfb, 0xd0, 0x14, 0x94, 0x4e, 0x22, 0x65, 0x16, 0x7d, 0xc4, 0x20,
95 0x01, 0x5b, 0x10, 0x64, 0x74, 0xb7, 0x22, 0x9a, 0x95, 0xd1, 0x48, 0x0c, 0xb9,
96 0xac, 0xd1, 0xa0, 0x28, 0xb7, 0x67
97 };
98
99 static const char *client_ats_label = "client application traffic secret";
100
101 static unsigned char client_ats[] = {
102 0x56, 0x9e, 0x9c, 0x17, 0xe3, 0x52, 0x1f, 0xdd, 0x09, 0xf4, 0xb8, 0x4f, 0x6c,
103 0xd6, 0x6d, 0xa8, 0x23, 0xde, 0xeb, 0x81, 0xbb, 0xb1, 0xde, 0x61, 0xe2, 0x82,
104 0x56, 0x27, 0xf7, 0x00, 0x63, 0x81,
105 };
106
107 static unsigned char client_ats_key[] = {
108 0xcb, 0xfa, 0xae, 0x71, 0x8d, 0xfb, 0x52, 0xba, 0x7b, 0x87, 0xde, 0x8b, 0x6d,
109 0xac, 0x92, 0x60
110 };
111
112 static unsigned char client_ats_iv[] = {
113 0x74, 0x86, 0x88, 0xe9, 0x7f, 0x72, 0xfb, 0xf3, 0x33, 0x1e, 0xfb, 0x55
114 };
115
116 static const char *server_ats_label = "server application traffic secret";
117
118 static unsigned char server_ats[] = {
119 0xd1, 0xbf, 0xdc, 0x8b, 0x84, 0xf4, 0x16, 0xb7, 0xc6, 0x90, 0xd9, 0xc9, 0x2c,
120 0x23, 0x11, 0xb3, 0x05, 0xad, 0x75, 0xfc, 0xe6, 0x29, 0x90, 0x2b, 0xe1, 0x03,
121 0xdd, 0x0c, 0x12, 0x51, 0xea, 0xd2,
122 };
123
124 static unsigned char server_ats_key[] = {
125 0x35, 0xc2, 0xd1, 0x54, 0xa8, 0x43, 0x03, 0xc6, 0x55, 0xa0, 0x2e, 0x5e, 0x1f,
126 0x82, 0x31, 0x62
127 };
128
129 static unsigned char server_ats_iv[] = {
130 0xe5, 0x77, 0xd9, 0x8a, 0xb3, 0x2e, 0xec, 0x79, 0xb1, 0x63, 0x68, 0xc2
131 };
132
133 /* Mocked out implementations of various functions */
134 int ssl3_digest_cached_records(SSL *s, int keep)
135 {
136     return 1;
137 }
138
139 static int full_hash = 0;
140
141 /* Give a hash of the currently set handshake */
142 int ssl_handshake_hash(SSL *s, unsigned char *out, size_t outlen,
143                        size_t *hashlen)
144 {
145     if (sizeof(hs_start_hash) > outlen
146             || sizeof(hs_full_hash) != sizeof(hs_start_hash))
147         return 0;
148
149     if (full_hash) {
150         memcpy(out, hs_full_hash, sizeof(hs_full_hash));
151         *hashlen = sizeof(hs_full_hash);
152     } else {
153         memcpy(out, hs_start_hash, sizeof(hs_start_hash));
154         *hashlen = sizeof(hs_start_hash);
155     }
156
157     return 1;
158 }
159
160 const EVP_MD *ssl_handshake_md(SSL *s)
161 {
162     return EVP_sha256();
163 }
164
165 void RECORD_LAYER_reset_read_sequence(RECORD_LAYER *rl)
166 {
167 }
168
169 void RECORD_LAYER_reset_write_sequence(RECORD_LAYER *rl)
170 {
171 }
172
173 int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc,
174                        const EVP_MD **md, int *mac_pkey_type,
175                        size_t *mac_secret_size, SSL_COMP **comp, int use_etm)
176
177 {
178     return 0;
179 }
180
181 /* End of mocked out code */
182
183 static int test_secret(SSL *s, unsigned char *prk,
184                        const unsigned char *label, size_t labellen,
185                        const unsigned char *ref_secret,
186                        const unsigned char *ref_key, const unsigned char *ref_iv)
187 {
188     size_t hashsize = EVP_MD_size(ssl_handshake_md(s));
189     unsigned char gensecret[EVP_MAX_MD_SIZE];
190     unsigned char key[KEYLEN];
191     unsigned char iv[IVLEN];
192
193     if (!tls13_derive_secret(s, prk, label, labellen, gensecret)) {
194         fprintf(stderr, "Secret generation failed\n");
195         return 0;
196     }
197
198     if (memcmp(gensecret, ref_secret, hashsize) != 0) {
199         fprintf(stderr, "Generated secret does not match\n");
200         return 0;
201     }
202
203     if (!tls13_derive_key(s, gensecret, key, KEYLEN)) {
204         fprintf(stderr, "Key generation failed\n");
205         return 0;
206     }
207
208     if (memcmp(key, ref_key, KEYLEN) != 0) {
209         fprintf(stderr, "Generated key does not match\n");
210         return 0;
211     }
212
213     if (!tls13_derive_iv(s, gensecret, iv, IVLEN)) {
214         fprintf(stderr, "IV generation failed\n");
215         return 0;
216     }
217
218     if (memcmp(iv, ref_iv, IVLEN) != 0) {
219         fprintf(stderr, "Generated IV does not match\n");
220         return 0;
221     }
222
223     return 1;
224 }
225
226 static int test_handshake_secrets(void)
227 {
228     SSL_CTX *ctx = NULL;
229     SSL *s = NULL;
230     int ret = 0;
231     size_t hashsize;
232     unsigned char out_master_secret[EVP_MAX_MD_SIZE];
233     size_t master_secret_length;
234
235     ctx = SSL_CTX_new(TLS_method());
236     if (ctx == NULL)
237         goto err;
238
239     s = SSL_new(ctx);
240     if (s == NULL)
241         goto err;
242
243     if (!tls13_generate_early_secret(s, NULL, 0)) {
244         fprintf(stderr, "Early secret generation failed\n");
245         goto err;
246     }
247
248     if (memcmp(s->early_secret, early_secret, sizeof(early_secret)) != 0) {
249         fprintf(stderr, "Early secret does not match\n");
250         goto err;
251     }
252
253     if (!tls13_generate_handshake_secret(s, ecdhe_secret,
254                                          sizeof(ecdhe_secret))) {
255         fprintf(stderr, "Hanshake secret generation failed\n");
256         goto err;
257     }
258
259     if (memcmp(s->handshake_secret, handshake_secret,
260                sizeof(handshake_secret)) != 0) {
261         fprintf(stderr, "Handshake secret does not match\n");
262         goto err;
263     }
264
265     hashsize = EVP_MD_size(ssl_handshake_md(s));
266     if (sizeof(client_hts) != hashsize || sizeof(client_hts_key) != KEYLEN
267             || sizeof(client_hts_iv) != IVLEN) {
268         fprintf(stderr, "Internal test error\n");
269         goto err;
270     }
271
272     if (!test_secret(s, s->handshake_secret, (unsigned char *)client_hts_label,
273                      strlen(client_hts_label), client_hts, client_hts_key,
274                      client_hts_iv)) {
275         fprintf(stderr, "Client handshake secret test failed\n");
276         goto err;
277     }
278
279     if (sizeof(server_hts) != hashsize || sizeof(server_hts_key) != KEYLEN
280             || sizeof(server_hts_iv) != IVLEN) {
281         fprintf(stderr, "Internal test error\n");
282         goto err;
283     }
284
285     if (!test_secret(s, s->handshake_secret, (unsigned char *)server_hts_label,
286                      strlen(server_hts_label), server_hts, server_hts_key,
287                      server_hts_iv)) {
288         fprintf(stderr, "Server handshake secret test failed\n");
289         goto err;
290     }
291
292     /*
293      * Ensure the mocked out ssl_handshake_hash() returns the full handshake
294      * hash.
295      */
296     full_hash = 1;
297
298     if (!tls13_generate_master_secret(s, out_master_secret,
299                                       s->handshake_secret, hashsize,
300                                       &master_secret_length)) {
301         fprintf(stderr, "Master secret generation failed\n");
302         goto err;
303     }
304
305     if (master_secret_length != sizeof(master_secret) ||
306             memcmp(out_master_secret, master_secret,
307                    sizeof(master_secret)) != 0) {
308         fprintf(stderr, "Master secret does not match\n");
309         goto err;
310     }
311
312     if (sizeof(client_ats) != hashsize || sizeof(client_ats_key) != KEYLEN
313             || sizeof(client_ats_iv) != IVLEN) {
314         fprintf(stderr, "Internal test error\n");
315         goto err;
316     }
317
318     if (!test_secret(s, out_master_secret, (unsigned char *)client_ats_label,
319                      strlen(client_ats_label), client_ats, client_ats_key,
320                      client_ats_iv)) {
321         fprintf(stderr, "Client application data secret test failed\n");
322         goto err;
323     }
324
325     if (sizeof(server_ats) != hashsize || sizeof(server_ats_key) != KEYLEN
326             || sizeof(server_ats_iv) != IVLEN) {
327         fprintf(stderr, "Internal test error\n");
328         goto err;
329     }
330
331     if (!test_secret(s, out_master_secret, (unsigned char *)server_ats_label,
332                      strlen(server_ats_label), server_ats, server_ats_key,
333                      server_ats_iv)) {
334         fprintf(stderr, "Server application data secret test failed\n");
335         goto err;
336     }
337
338     ret = 1;
339  err:
340     SSL_free(s);
341     SSL_CTX_free(ctx);
342     return ret;
343 }
344
345 int main(int argc, char *argv[])
346 {
347     BIO *err = NULL;
348     int testresult = 1;
349
350     err = BIO_new_fp(stderr, BIO_NOCLOSE | BIO_FP_TEXT);
351
352     CRYPTO_set_mem_debug(1);
353     CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
354
355     ADD_TEST(test_handshake_secrets);
356
357     testresult = run_tests(argv[0]);
358
359 #ifndef OPENSSL_NO_CRYPTO_MDEBUG
360     if (CRYPTO_mem_leaks(err) <= 0)
361         testresult = 1;
362 #endif
363     BIO_free(err);
364
365     if (!testresult)
366         fprintf(stderr, "PASS\n");
367
368     return testresult;
369 }