Implement tls13_change_cipher_state()
[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 /* End of mocked out code */
174
175 static int test_secret(SSL *s, unsigned char *prk,
176                        const unsigned char *label, size_t labellen,
177                        const unsigned char *ref_secret,
178                        const unsigned char *ref_key, const unsigned char *ref_iv)
179 {
180     size_t hashsize = EVP_MD_size(ssl_handshake_md(s));
181     unsigned char gensecret[EVP_MAX_MD_SIZE];
182     unsigned char key[KEYLEN];
183     unsigned char iv[IVLEN];
184
185     if (!tls13_derive_secret(s, prk, label, labellen, gensecret)) {
186         fprintf(stderr, "Secret generation failed\n");
187         return 0;
188     }
189
190     if (memcmp(gensecret, ref_secret, hashsize) != 0) {
191         fprintf(stderr, "Generated secret does not match\n");
192         return 0;
193     }
194
195     if (!tls13_derive_key(s, gensecret, key, KEYLEN)) {
196         fprintf(stderr, "Key generation failed\n");
197         return 0;
198     }
199
200     if (memcmp(key, ref_key, KEYLEN) != 0) {
201         fprintf(stderr, "Generated key does not match\n");
202         return 0;
203     }
204
205     if (!tls13_derive_iv(s, gensecret, iv, IVLEN)) {
206         fprintf(stderr, "IV generation failed\n");
207         return 0;
208     }
209
210     if (memcmp(iv, ref_iv, IVLEN) != 0) {
211         fprintf(stderr, "Generated IV does not match\n");
212         return 0;
213     }
214
215     return 1;
216 }
217
218 static int test_handshake_secrets(void)
219 {
220     SSL_CTX *ctx = NULL;
221     SSL *s = NULL;
222     int ret = 0;
223     size_t hashsize;
224     unsigned char out_master_secret[EVP_MAX_MD_SIZE];
225     size_t master_secret_length;
226
227     ctx = SSL_CTX_new(TLS_method());
228     if (ctx == NULL)
229         goto err;
230
231     s = SSL_new(ctx);
232     if (s == NULL)
233         goto err;
234
235     if (!tls13_generate_early_secret(s, NULL, 0)) {
236         fprintf(stderr, "Early secret generation failed\n");
237         goto err;
238     }
239
240     if (memcmp(s->early_secret, early_secret, sizeof(early_secret)) != 0) {
241         fprintf(stderr, "Early secret does not match\n");
242         goto err;
243     }
244
245     if (!tls13_generate_handshake_secret(s, ecdhe_secret,
246                                          sizeof(ecdhe_secret))) {
247         fprintf(stderr, "Hanshake secret generation failed\n");
248         goto err;
249     }
250
251     if (memcmp(s->handshake_secret, handshake_secret,
252                sizeof(handshake_secret)) != 0) {
253         fprintf(stderr, "Handshake secret does not match\n");
254         goto err;
255     }
256
257     hashsize = EVP_MD_size(ssl_handshake_md(s));
258     if (sizeof(client_hts) != hashsize || sizeof(client_hts_key) != KEYLEN
259             || sizeof(client_hts_iv) != IVLEN) {
260         fprintf(stderr, "Internal test error\n");
261         goto err;
262     }
263
264     if (!test_secret(s, s->handshake_secret, (unsigned char *)client_hts_label,
265                      strlen(client_hts_label), client_hts, client_hts_key,
266                      client_hts_iv)) {
267         fprintf(stderr, "Client handshake secret test failed\n");
268         goto err;
269     }
270
271     if (sizeof(server_hts) != hashsize || sizeof(server_hts_key) != KEYLEN
272             || sizeof(server_hts_iv) != IVLEN) {
273         fprintf(stderr, "Internal test error\n");
274         goto err;
275     }
276
277     if (!test_secret(s, s->handshake_secret, (unsigned char *)server_hts_label,
278                      strlen(server_hts_label), server_hts, server_hts_key,
279                      server_hts_iv)) {
280         fprintf(stderr, "Server handshake secret test failed\n");
281         goto err;
282     }
283
284     /*
285      * Ensure the mocked out ssl_handshake_hash() returns the full handshake
286      * hash.
287      */
288     full_hash = 1;
289
290     if (!tls13_generate_master_secret(s, out_master_secret,
291                                       s->handshake_secret, hashsize,
292                                       &master_secret_length)) {
293         fprintf(stderr, "Master secret generation failed\n");
294         goto err;
295     }
296
297     if (master_secret_length != sizeof(master_secret) ||
298             memcmp(out_master_secret, master_secret,
299                    sizeof(master_secret)) != 0) {
300         fprintf(stderr, "Master secret does not match\n");
301         goto err;
302     }
303
304     if (sizeof(client_ats) != hashsize || sizeof(client_ats_key) != KEYLEN
305             || sizeof(client_ats_iv) != IVLEN) {
306         fprintf(stderr, "Internal test error\n");
307         goto err;
308     }
309
310     if (!test_secret(s, out_master_secret, (unsigned char *)client_ats_label,
311                      strlen(client_ats_label), client_ats, client_ats_key,
312                      client_ats_iv)) {
313         fprintf(stderr, "Client application data secret test failed\n");
314         goto err;
315     }
316
317     if (sizeof(server_ats) != hashsize || sizeof(server_ats_key) != KEYLEN
318             || sizeof(server_ats_iv) != IVLEN) {
319         fprintf(stderr, "Internal test error\n");
320         goto err;
321     }
322
323     if (!test_secret(s, out_master_secret, (unsigned char *)server_ats_label,
324                      strlen(server_ats_label), server_ats, server_ats_key,
325                      server_ats_iv)) {
326         fprintf(stderr, "Server application data secret test failed\n");
327         goto err;
328     }
329
330     ret = 1;
331  err:
332     SSL_free(s);
333     SSL_CTX_free(ctx);
334     return ret;
335 }
336
337 int main(int argc, char *argv[])
338 {
339     BIO *err = NULL;
340     int testresult = 1;
341
342     err = BIO_new_fp(stderr, BIO_NOCLOSE | BIO_FP_TEXT);
343
344     CRYPTO_set_mem_debug(1);
345     CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
346
347     ADD_TEST(test_handshake_secrets);
348
349     testresult = run_tests(argv[0]);
350
351 #ifndef OPENSSL_NO_CRYPTO_MDEBUG
352     if (CRYPTO_mem_leaks(err) <= 0)
353         testresult = 1;
354 #endif
355     BIO_free(err);
356
357     if (!testresult)
358         fprintf(stderr, "PASS\n");
359
360     return testresult;
361 }