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