]>
Commit | Line | Data |
---|---|---|
34574f19 MC |
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 <stdlib.h> | |
11 | #include "ssl_locl.h" | |
12 | #include <openssl/evp.h> | |
13 | #include <openssl/kdf.h> | |
14 | ||
15 | #define TLS13_MAX_LABEL_LEN 246 | |
16 | ||
17 | /* Always filled with zeros */ | |
18 | static const unsigned char default_zeros[EVP_MAX_MD_SIZE]; | |
19 | ||
34574f19 MC |
20 | /* |
21 | * Given a |secret|; a |label| of length |labellen|; and a |hash| of the | |
22 | * handshake messages, derive a new secret |outlen| bytes long and store it in | |
f5ca0b04 MC |
23 | * the location pointed to be |out|. The |hash| value may be NULL. Returns 1 on |
24 | * success 0 on failure. | |
34574f19 MC |
25 | */ |
26 | static int tls13_hkdf_expand(SSL *s, const unsigned char *secret, | |
27 | const unsigned char *label, size_t labellen, | |
28 | const unsigned char *hash, | |
29 | unsigned char *out, size_t outlen) | |
30 | { | |
31 | const unsigned char label_prefix[] = "TLS 1.3, "; | |
32 | const EVP_MD *md = ssl_handshake_md(s); | |
33 | EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, NULL); | |
34 | int ret; | |
35 | size_t hkdflabellen; | |
36 | size_t hashlen; | |
37 | /* | |
38 | * 2 bytes for length of whole HkdfLabel + 1 byte for length of combined | |
39 | * prefix and label + bytes for the label itself + bytes for the hash | |
40 | */ | |
41 | unsigned char hkdflabel[sizeof(uint16_t) + sizeof(uint8_t) + | |
42 | + sizeof(label_prefix) + TLS13_MAX_LABEL_LEN | |
43 | + EVP_MAX_MD_SIZE]; | |
44 | WPACKET pkt; | |
45 | ||
46 | if (pctx == NULL) | |
47 | return 0; | |
48 | ||
49 | hashlen = EVP_MD_size(md); | |
50 | ||
51 | if (!WPACKET_init_static_len(&pkt, hkdflabel, sizeof(hkdflabel), 0) | |
52 | || !WPACKET_put_bytes_u16(&pkt, outlen) | |
53 | || !WPACKET_start_sub_packet_u8(&pkt) | |
54 | || !WPACKET_memcpy(&pkt, label_prefix, sizeof(label_prefix) - 1) | |
55 | || !WPACKET_memcpy(&pkt, label, labellen) | |
56 | || !WPACKET_close(&pkt) | |
57 | || !WPACKET_sub_memcpy_u8(&pkt, hash, (hash == NULL) ? 0 : hashlen) | |
58 | || !WPACKET_get_total_written(&pkt, &hkdflabellen) | |
59 | || !WPACKET_finish(&pkt)) { | |
60 | WPACKET_cleanup(&pkt); | |
61 | return 0; | |
62 | } | |
63 | ||
64 | ret = EVP_PKEY_derive_init(pctx) <= 0 | |
65 | || EVP_PKEY_CTX_hkdf_mode(pctx, EVP_PKEY_HKDEF_MODE_EXPAND_ONLY) | |
66 | <= 0 | |
67 | || EVP_PKEY_CTX_set_hkdf_md(pctx, md) <= 0 | |
68 | || EVP_PKEY_CTX_set1_hkdf_key(pctx, secret, hashlen) <= 0 | |
69 | || EVP_PKEY_CTX_add1_hkdf_info(pctx, hkdflabel, hkdflabellen) <= 0 | |
70 | || EVP_PKEY_derive(pctx, out, &outlen) <= 0; | |
71 | ||
72 | EVP_PKEY_CTX_free(pctx); | |
73 | ||
74 | return ret == 0; | |
75 | } | |
76 | ||
77 | /* | |
78 | * Given a input secret |insecret| and a |label| of length |labellen|, derive a | |
79 | * new |secret|. This will be the length of the current hash output size and | |
f5ca0b04 MC |
80 | * will be based on the current state of the handshake hashes. Returns 1 on |
81 | * success 0 on failure. | |
34574f19 MC |
82 | */ |
83 | int tls13_derive_secret(SSL *s, const unsigned char *insecret, | |
84 | const unsigned char *label, size_t labellen, | |
85 | unsigned char *secret) | |
86 | { | |
87 | unsigned char hash[EVP_MAX_MD_SIZE]; | |
88 | size_t hashlen; | |
89 | ||
90 | if (!ssl3_digest_cached_records(s, 1)) | |
91 | return 0; | |
92 | ||
93 | if (!ssl_handshake_hash(s, hash, sizeof(hash), &hashlen)) | |
94 | return 0; | |
95 | ||
96 | return tls13_hkdf_expand(s, insecret, label, labellen, hash, secret, | |
97 | hashlen); | |
98 | } | |
99 | ||
100 | /* | |
f5ca0b04 MC |
101 | * Given a |secret| generate a |key| of length |keylen| bytes. Returns 1 on |
102 | * success 0 on failure. | |
34574f19 MC |
103 | */ |
104 | int tls13_derive_key(SSL *s, const unsigned char *secret, unsigned char *key, | |
105 | size_t keylen) | |
106 | { | |
f5ca0b04 MC |
107 | static const unsigned char keylabel[] = "key"; |
108 | ||
34574f19 MC |
109 | return tls13_hkdf_expand(s, secret, keylabel, sizeof(keylabel) - 1, NULL, |
110 | key, keylen); | |
111 | } | |
112 | ||
113 | /* | |
f5ca0b04 MC |
114 | * Given a |secret| generate an |iv| of length |ivlen| bytes. Returns 1 on |
115 | * success 0 on failure. | |
34574f19 MC |
116 | */ |
117 | int tls13_derive_iv(SSL *s, const unsigned char *secret, unsigned char *iv, | |
118 | size_t ivlen) | |
119 | { | |
f5ca0b04 MC |
120 | static const unsigned char ivlabel[] = "iv"; |
121 | ||
34574f19 MC |
122 | return tls13_hkdf_expand(s, secret, ivlabel, sizeof(ivlabel) - 1, NULL, |
123 | iv, ivlen); | |
124 | } | |
125 | ||
6484776f MC |
126 | static int tls13_derive_finishedkey(SSL *s, const unsigned char *secret, |
127 | unsigned char *fin, size_t finlen) | |
128 | { | |
f5ca0b04 MC |
129 | static const unsigned char finishedlabel[] = "finished"; |
130 | ||
6484776f MC |
131 | return tls13_hkdf_expand(s, secret, finishedlabel, |
132 | sizeof(finishedlabel) - 1, NULL, fin, finlen); | |
133 | } | |
134 | ||
34574f19 MC |
135 | /* |
136 | * Given the previous secret |prevsecret| and a new input secret |insecret| of | |
137 | * length |insecretlen|, generate a new secret and store it in the location | |
f5ca0b04 | 138 | * pointed to by |outsecret|. Returns 1 on success 0 on failure. |
34574f19 MC |
139 | */ |
140 | static int tls13_generate_secret(SSL *s, const unsigned char *prevsecret, | |
141 | const unsigned char *insecret, | |
142 | size_t insecretlen, | |
143 | unsigned char *outsecret) | |
144 | { | |
145 | const EVP_MD *md = ssl_handshake_md(s); | |
146 | size_t mdlen, prevsecretlen; | |
147 | int ret; | |
148 | EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, NULL); | |
149 | ||
150 | if (pctx == NULL) | |
151 | return 0; | |
152 | ||
153 | mdlen = EVP_MD_size(md); | |
154 | ||
155 | if (insecret == NULL) { | |
156 | insecret = default_zeros; | |
157 | insecretlen = mdlen; | |
158 | } | |
159 | if (prevsecret == NULL) { | |
160 | prevsecret = default_zeros; | |
161 | prevsecretlen = 0; | |
162 | } else { | |
163 | prevsecretlen = mdlen; | |
164 | } | |
165 | ||
166 | ret = EVP_PKEY_derive_init(pctx) <= 0 | |
167 | || EVP_PKEY_CTX_hkdf_mode(pctx, EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY) | |
168 | <= 0 | |
169 | || EVP_PKEY_CTX_set_hkdf_md(pctx, md) <= 0 | |
170 | || EVP_PKEY_CTX_set1_hkdf_key(pctx, insecret, insecretlen) <= 0 | |
171 | || EVP_PKEY_CTX_set1_hkdf_salt(pctx, prevsecret, prevsecretlen) | |
172 | <= 0 | |
173 | || EVP_PKEY_derive(pctx, outsecret, &mdlen) | |
174 | <= 0; | |
175 | ||
176 | EVP_PKEY_CTX_free(pctx); | |
177 | return ret == 0; | |
178 | } | |
179 | ||
180 | /* | |
181 | * Given an input secret |insecret| of length |insecretlen| generate the early | |
f5ca0b04 | 182 | * secret. Returns 1 on success 0 on failure. |
34574f19 MC |
183 | */ |
184 | int tls13_generate_early_secret(SSL *s, const unsigned char *insecret, | |
185 | size_t insecretlen) | |
186 | { | |
187 | return tls13_generate_secret(s, NULL, insecret, insecretlen, | |
188 | (unsigned char *)&s->early_secret); | |
189 | } | |
190 | ||
191 | /* | |
192 | * Given an input secret |insecret| of length |insecretlen| generate the | |
193 | * handshake secret. This requires the early secret to already have been | |
f5ca0b04 | 194 | * generated. Returns 1 on success 0 on failure. |
34574f19 MC |
195 | */ |
196 | int tls13_generate_handshake_secret(SSL *s, const unsigned char *insecret, | |
197 | size_t insecretlen) | |
198 | { | |
199 | return tls13_generate_secret(s, s->early_secret, insecret, insecretlen, | |
200 | (unsigned char *)&s->handshake_secret); | |
201 | } | |
202 | ||
203 | /* | |
204 | * Given the handshake secret |prev| of length |prevlen| generate the master | |
f5ca0b04 MC |
205 | * secret and store its length in |*secret_size|. Returns 1 on success 0 on |
206 | * failure. | |
34574f19 MC |
207 | */ |
208 | int tls13_generate_master_secret(SSL *s, unsigned char *out, | |
209 | unsigned char *prev, size_t prevlen, | |
210 | size_t *secret_size) | |
211 | { | |
212 | *secret_size = EVP_MD_size(ssl_handshake_md(s)); | |
213 | return tls13_generate_secret(s, prev, NULL, 0, out); | |
214 | } | |
215 | ||
92760c21 | 216 | /* |
f5ca0b04 MC |
217 | * Generates the mac for the Finished message. Returns the length of the MAC or |
218 | * 0 on error. | |
92760c21 MC |
219 | */ |
220 | size_t tls13_final_finish_mac(SSL *s, const char *str, size_t slen, | |
221 | unsigned char *out) | |
222 | { | |
6484776f MC |
223 | const EVP_MD *md = ssl_handshake_md(s); |
224 | unsigned char hash[EVP_MAX_MD_SIZE]; | |
225 | size_t hashlen, ret = 0; | |
226 | EVP_PKEY *key = NULL; | |
227 | EVP_MD_CTX *ctx = EVP_MD_CTX_new(); | |
92760c21 | 228 | |
6484776f MC |
229 | if (!ssl_handshake_hash(s, hash, sizeof(hash), &hashlen)) |
230 | goto err; | |
231 | ||
232 | if (str == s->method->ssl3_enc->server_finished_label) | |
233 | key = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, | |
234 | s->server_finished_secret, hashlen); | |
235 | else | |
236 | key = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, | |
237 | s->client_finished_secret, hashlen); | |
238 | ||
239 | if (key == NULL | |
240 | || ctx == NULL | |
241 | || EVP_DigestSignInit(ctx, NULL, md, NULL, key) <= 0 | |
242 | || EVP_DigestSignUpdate(ctx, hash, hashlen) <= 0 | |
243 | || EVP_DigestSignFinal(ctx, out, &hashlen) <= 0) | |
244 | goto err; | |
92760c21 | 245 | |
6484776f MC |
246 | ret = hashlen; |
247 | err: | |
248 | EVP_PKEY_free(key); | |
249 | EVP_MD_CTX_free(ctx); | |
250 | return ret; | |
92760c21 MC |
251 | } |
252 | ||
253 | /* | |
254 | * There isn't really a key block in TLSv1.3, but we still need this function | |
f5ca0b04 | 255 | * for initialising the cipher and hash. Returns 1 on success or 0 on failure. |
92760c21 MC |
256 | */ |
257 | int tls13_setup_key_block(SSL *s) | |
258 | { | |
259 | const EVP_CIPHER *c; | |
260 | const EVP_MD *hash; | |
261 | int mac_type = NID_undef; | |
262 | ||
263 | s->session->cipher = s->s3->tmp.new_cipher; | |
264 | if (!ssl_cipher_get_evp | |
265 | (s->session, &c, &hash, &mac_type, NULL, NULL, 0)) { | |
266 | SSLerr(SSL_F_TLS13_SETUP_KEY_BLOCK, SSL_R_CIPHER_OR_HASH_UNAVAILABLE); | |
267 | return 0; | |
268 | } | |
269 | ||
270 | s->s3->tmp.new_sym_enc = c; | |
271 | s->s3->tmp.new_hash = hash; | |
272 | ||
273 | return 1; | |
274 | } | |
275 | ||
0d9824c1 MC |
276 | int tls13_change_cipher_state(SSL *s, int which) |
277 | { | |
f5ca0b04 MC |
278 | static const unsigned char client_handshake_traffic[] = |
279 | "client handshake traffic secret"; | |
280 | static const unsigned char client_application_traffic[] = | |
281 | "client application traffic secret"; | |
282 | static const unsigned char server_handshake_traffic[] = | |
283 | "server handshake traffic secret"; | |
284 | static const unsigned char server_application_traffic[] = | |
285 | "server application traffic secret"; | |
0d9824c1 | 286 | unsigned char key[EVP_MAX_KEY_LENGTH]; |
bebc0c7d | 287 | unsigned char *iv; |
0d9824c1 MC |
288 | unsigned char secret[EVP_MAX_MD_SIZE]; |
289 | unsigned char *insecret; | |
6484776f | 290 | unsigned char *finsecret = NULL; |
0d9824c1 | 291 | EVP_CIPHER_CTX *ciph_ctx; |
902d036c | 292 | const EVP_CIPHER *ciph = s->s3->tmp.new_sym_enc; |
0528f253 | 293 | size_t ivlen, keylen, finsecretlen = 0; |
0d9824c1 MC |
294 | const unsigned char *label; |
295 | size_t labellen; | |
6530c490 | 296 | int ret = 0; |
0d9824c1 MC |
297 | |
298 | if (which & SSL3_CC_READ) { | |
299 | if (s->enc_read_ctx != NULL) { | |
300 | EVP_CIPHER_CTX_reset(s->enc_read_ctx); | |
301 | } else { | |
302 | s->enc_read_ctx = EVP_CIPHER_CTX_new(); | |
303 | if (s->enc_read_ctx == NULL) { | |
304 | SSLerr(SSL_F_TLS13_CHANGE_CIPHER_STATE, ERR_R_MALLOC_FAILURE); | |
305 | goto err; | |
306 | } | |
307 | } | |
308 | ciph_ctx = s->enc_read_ctx; | |
bebc0c7d | 309 | iv = s->read_iv; |
0d9824c1 MC |
310 | |
311 | RECORD_LAYER_reset_read_sequence(&s->rlayer); | |
312 | } else { | |
313 | if (s->enc_write_ctx != NULL) { | |
314 | EVP_CIPHER_CTX_reset(s->enc_write_ctx); | |
315 | } else { | |
316 | s->enc_write_ctx = EVP_CIPHER_CTX_new(); | |
317 | if (s->enc_write_ctx == NULL) { | |
318 | SSLerr(SSL_F_TLS13_CHANGE_CIPHER_STATE, ERR_R_MALLOC_FAILURE); | |
319 | goto err; | |
320 | } | |
321 | } | |
322 | ciph_ctx = s->enc_write_ctx; | |
bebc0c7d | 323 | iv = s->write_iv; |
0d9824c1 MC |
324 | |
325 | RECORD_LAYER_reset_write_sequence(&s->rlayer); | |
326 | } | |
327 | ||
328 | if (((which & SSL3_CC_CLIENT) && (which & SSL3_CC_WRITE)) | |
329 | || ((which & SSL3_CC_SERVER) && (which & SSL3_CC_READ))) { | |
330 | if (which & SSL3_CC_HANDSHAKE) { | |
331 | insecret = s->handshake_secret; | |
6484776f MC |
332 | finsecret = s->client_finished_secret; |
333 | finsecretlen = sizeof(s->client_finished_secret); | |
0d9824c1 MC |
334 | label = client_handshake_traffic; |
335 | labellen = sizeof(client_handshake_traffic) - 1; | |
336 | } else { | |
337 | insecret = s->session->master_key; | |
338 | label = client_application_traffic; | |
339 | labellen = sizeof(client_application_traffic) - 1; | |
340 | } | |
341 | } else { | |
342 | if (which & SSL3_CC_HANDSHAKE) { | |
343 | insecret = s->handshake_secret; | |
6484776f MC |
344 | finsecret = s->server_finished_secret; |
345 | finsecretlen = sizeof(s->server_finished_secret); | |
0d9824c1 MC |
346 | label = server_handshake_traffic; |
347 | labellen = sizeof(server_handshake_traffic) - 1; | |
348 | } else { | |
349 | insecret = s->session->master_key; | |
350 | label = server_application_traffic; | |
351 | labellen = sizeof(server_application_traffic) - 1; | |
352 | } | |
353 | } | |
354 | ||
355 | if (!tls13_derive_secret(s, insecret, label, labellen, secret)) { | |
356 | SSLerr(SSL_F_TLS13_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR); | |
357 | goto err; | |
358 | } | |
359 | ||
360 | /* TODO(size_t): convert me */ | |
361 | keylen = EVP_CIPHER_key_length(ciph); | |
bebc0c7d | 362 | ivlen = EVP_CIPHER_iv_length(ciph); |
0d9824c1 MC |
363 | |
364 | if (!tls13_derive_key(s, secret, key, keylen) | |
6484776f MC |
365 | || !tls13_derive_iv(s, secret, iv, ivlen) |
366 | || (finsecret != NULL && !tls13_derive_finishedkey(s, secret, | |
367 | finsecret, | |
368 | finsecretlen))) { | |
0d9824c1 MC |
369 | SSLerr(SSL_F_TLS13_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR); |
370 | goto err; | |
371 | } | |
372 | ||
bebc0c7d MC |
373 | if (EVP_CipherInit_ex(ciph_ctx, ciph, NULL, key, NULL, |
374 | (which & SSL3_CC_WRITE)) <= 0) { | |
375 | SSLerr(SSL_F_TLS13_CHANGE_CIPHER_STATE, ERR_R_EVP_LIB); | |
376 | goto err; | |
0d9824c1 MC |
377 | } |
378 | ||
379 | #ifdef OPENSSL_SSL_TRACE_CRYPTO | |
380 | if (s->msg_callback) { | |
381 | int wh = which & SSL3_CC_WRITE ? TLS1_RT_CRYPTO_WRITE : 0; | |
382 | ||
383 | if (ciph->key_len) | |
384 | s->msg_callback(2, s->version, wh | TLS1_RT_CRYPTO_KEY, | |
385 | key, ciph->key_len, s, s->msg_callback_arg); | |
bebc0c7d MC |
386 | |
387 | wh |= TLS1_RT_CRYPTO_IV; | |
388 | s->msg_callback(2, s->version, wh, iv, ivlen, s, | |
389 | s->msg_callback_arg); | |
0d9824c1 MC |
390 | } |
391 | #endif | |
392 | ||
6530c490 | 393 | ret = 1; |
0d9824c1 MC |
394 | err: |
395 | OPENSSL_cleanse(secret, sizeof(secret)); | |
396 | OPENSSL_cleanse(key, sizeof(key)); | |
6530c490 | 397 | return ret; |
0d9824c1 | 398 | } |