]>
Commit | Line | Data |
---|---|---|
846e33c7 | 1 | /* |
b6461792 | 2 | * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved. |
c80149d9 | 3 | * Copyright 2005 Nokia. All rights reserved. |
82b0bf0b | 4 | * |
2c18d164 | 5 | * Licensed under the Apache License 2.0 (the "License"). You may not use |
846e33c7 RS |
6 | * this file except in compliance with the License. You can obtain a copy |
7 | * in the file LICENSE in the source distribution or at | |
8 | * https://www.openssl.org/source/license.html | |
82b0bf0b | 9 | */ |
846e33c7 | 10 | |
58964a49 | 11 | #include <stdio.h> |
706457b7 DMSP |
12 | #include "ssl_local.h" |
13 | #include "record/record_local.h" | |
50ec7505 BP |
14 | #include "internal/ktls.h" |
15 | #include "internal/cryptlib.h" | |
3c27208f | 16 | #include <openssl/comp.h> |
ec577822 | 17 | #include <openssl/evp.h> |
b7d60e76 | 18 | #include <openssl/kdf.h> |
637f374a | 19 | #include <openssl/rand.h> |
50ec7505 | 20 | #include <openssl/obj_mac.h> |
ce3b1bb4 | 21 | #include <openssl/core_names.h> |
49b26f54 | 22 | #include <openssl/trace.h> |
58964a49 | 23 | |
b7d60e76 | 24 | /* seed1 through seed5 are concatenated */ |
38b051a1 | 25 | static int tls1_PRF(SSL_CONNECTION *s, |
6db6bc5a MC |
26 | const void *seed1, size_t seed1_len, |
27 | const void *seed2, size_t seed2_len, | |
28 | const void *seed3, size_t seed3_len, | |
29 | const void *seed4, size_t seed4_len, | |
30 | const void *seed5, size_t seed5_len, | |
31 | const unsigned char *sec, size_t slen, | |
d4d2f3a4 | 32 | unsigned char *out, size_t olen, int fatal) |
0f113f3e | 33 | { |
28ba2541 | 34 | const EVP_MD *md = ssl_prf_md(s); |
ce3b1bb4 | 35 | EVP_KDF *kdf; |
32495464 | 36 | EVP_KDF_CTX *kctx = NULL; |
ce3b1bb4 | 37 | OSSL_PARAM params[8], *p = params; |
7e56c626 | 38 | const char *mdname; |
0f113f3e | 39 | |
28ba2541 | 40 | if (md == NULL) { |
668f6f08 | 41 | /* Should never happen */ |
d4d2f3a4 | 42 | if (fatal) |
c48ffbcc | 43 | SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); |
d4d2f3a4 | 44 | else |
6849b73c | 45 | ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); |
28ba2541 | 46 | return 0; |
668f6f08 | 47 | } |
38b051a1 TM |
48 | kdf = EVP_KDF_fetch(SSL_CONNECTION_GET_CTX(s)->libctx, |
49 | OSSL_KDF_NAME_TLS1_PRF, | |
50 | SSL_CONNECTION_GET_CTX(s)->propq); | |
ce3b1bb4 P |
51 | if (kdf == NULL) |
52 | goto err; | |
660c5344 | 53 | kctx = EVP_KDF_CTX_new(kdf); |
ce3b1bb4 P |
54 | EVP_KDF_free(kdf); |
55 | if (kctx == NULL) | |
b7d60e76 | 56 | goto err; |
ed576acd | 57 | mdname = EVP_MD_get0_name(md); |
ce3b1bb4 | 58 | *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, |
8b6ffd40 | 59 | (char *)mdname, 0); |
ce3b1bb4 P |
60 | *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SECRET, |
61 | (unsigned char *)sec, | |
62 | (size_t)slen); | |
63 | *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SEED, | |
64 | (void *)seed1, (size_t)seed1_len); | |
65 | *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SEED, | |
66 | (void *)seed2, (size_t)seed2_len); | |
67 | *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SEED, | |
68 | (void *)seed3, (size_t)seed3_len); | |
69 | *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SEED, | |
70 | (void *)seed4, (size_t)seed4_len); | |
71 | *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SEED, | |
72 | (void *)seed5, (size_t)seed5_len); | |
73 | *p = OSSL_PARAM_construct_end(); | |
5cceedb5 | 74 | if (EVP_KDF_derive(kctx, out, olen, params)) { |
660c5344 | 75 | EVP_KDF_CTX_free(kctx); |
ce3b1bb4 | 76 | return 1; |
d4d2f3a4 | 77 | } |
b7d60e76 | 78 | |
a230b26e | 79 | err: |
ce3b1bb4 | 80 | if (fatal) |
c48ffbcc | 81 | SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); |
ce3b1bb4 | 82 | else |
6849b73c | 83 | ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); |
660c5344 | 84 | EVP_KDF_CTX_free(kctx); |
ce3b1bb4 | 85 | return 0; |
81025661 | 86 | } |
0f113f3e | 87 | |
38b051a1 TM |
88 | static int tls1_generate_key_block(SSL_CONNECTION *s, unsigned char *km, |
89 | size_t num) | |
0f113f3e MC |
90 | { |
91 | int ret; | |
d4d2f3a4 MC |
92 | |
93 | /* Calls SSLfatal() as required */ | |
28ba2541 | 94 | ret = tls1_PRF(s, |
0f113f3e | 95 | TLS_MD_KEY_EXPANSION_CONST, |
555cbb32 TS |
96 | TLS_MD_KEY_EXPANSION_CONST_SIZE, s->s3.server_random, |
97 | SSL3_RANDOM_SIZE, s->s3.client_random, SSL3_RANDOM_SIZE, | |
0f113f3e | 98 | NULL, 0, NULL, 0, s->session->master_key, |
d4d2f3a4 | 99 | s->session->master_key_length, km, num, 1); |
55a9a16f | 100 | |
0f113f3e MC |
101 | return ret; |
102 | } | |
58964a49 | 103 | |
62f27ab9 MM |
104 | static int tls_iv_length_within_key_block(const EVP_CIPHER *c) |
105 | { | |
106 | /* If GCM/CCM mode only part of IV comes from PRF */ | |
ed576acd | 107 | if (EVP_CIPHER_get_mode(c) == EVP_CIPH_GCM_MODE) |
62f27ab9 | 108 | return EVP_GCM_TLS_FIXED_IV_LEN; |
ed576acd | 109 | else if (EVP_CIPHER_get_mode(c) == EVP_CIPH_CCM_MODE) |
62f27ab9 MM |
110 | return EVP_CCM_TLS_FIXED_IV_LEN; |
111 | else | |
ed576acd | 112 | return EVP_CIPHER_get_iv_length(c); |
62f27ab9 MM |
113 | } |
114 | ||
38b051a1 | 115 | int tls1_change_cipher_state(SSL_CONNECTION *s, int which) |
0f113f3e | 116 | { |
0f113f3e | 117 | unsigned char *p, *mac_secret; |
aedbb71b | 118 | unsigned char *key, *iv; |
0f113f3e | 119 | const EVP_CIPHER *c; |
976b263d | 120 | const SSL_COMP *comp = NULL; |
0f113f3e MC |
121 | const EVP_MD *m; |
122 | int mac_type; | |
aedbb71b | 123 | size_t mac_secret_size; |
b43d1cbb | 124 | size_t n, i, j, k, cl; |
cc110a0a | 125 | int iivlen; |
cc110a0a MC |
126 | /* |
127 | * Taglen is only relevant for CCM ciphersuites. Other ciphersuites | |
128 | * ignore this value so we can default it to 0. | |
129 | */ | |
130 | size_t taglen = 0; | |
faa3e66c | 131 | int direction; |
e2d5742b | 132 | |
555cbb32 TS |
133 | c = s->s3.tmp.new_sym_enc; |
134 | m = s->s3.tmp.new_hash; | |
135 | mac_type = s->s3.tmp.new_mac_pkey_type; | |
09b6c2ef | 136 | #ifndef OPENSSL_NO_COMP |
555cbb32 | 137 | comp = s->s3.tmp.new_compression; |
09b6c2ef | 138 | #endif |
58964a49 | 139 | |
aedbb71b MC |
140 | p = s->s3.tmp.key_block; |
141 | i = mac_secret_size = s->s3.tmp.new_mac_secret_size; | |
28a31a0a | 142 | |
aedbb71b MC |
143 | cl = EVP_CIPHER_get_key_length(c); |
144 | j = cl; | |
cc110a0a MC |
145 | iivlen = tls_iv_length_within_key_block(c); |
146 | if (iivlen < 0) { | |
147 | SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); | |
148 | goto err; | |
149 | } | |
150 | k = iivlen; | |
aedbb71b MC |
151 | if ((which == SSL3_CHANGE_CIPHER_CLIENT_WRITE) || |
152 | (which == SSL3_CHANGE_CIPHER_SERVER_READ)) { | |
153 | mac_secret = &(p[0]); | |
154 | n = i + i; | |
155 | key = &(p[n]); | |
156 | n += j + j; | |
157 | iv = &(p[n]); | |
158 | n += k + k; | |
159 | } else { | |
160 | n = i; | |
161 | mac_secret = &(p[n]); | |
162 | n += i + j; | |
163 | key = &(p[n]); | |
164 | n += j + k; | |
165 | iv = &(p[n]); | |
166 | n += k; | |
167 | } | |
0f113f3e | 168 | |
aedbb71b MC |
169 | if (n > s->s3.tmp.key_block_length) { |
170 | SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); | |
171 | goto err; | |
172 | } | |
5a5530a2 | 173 | |
b05fbac1 MC |
174 | switch (EVP_CIPHER_get_mode(c)) { |
175 | case EVP_CIPH_GCM_MODE: | |
176 | taglen = EVP_GCM_TLS_TAG_LEN; | |
177 | break; | |
178 | case EVP_CIPH_CCM_MODE: | |
cc110a0a MC |
179 | if ((s->s3.tmp.new_cipher->algorithm_enc |
180 | & (SSL_AES128CCM8 | SSL_AES256CCM8)) != 0) | |
181 | taglen = EVP_CCM8_TLS_TAG_LEN; | |
182 | else | |
183 | taglen = EVP_CCM_TLS_TAG_LEN; | |
b05fbac1 MC |
184 | break; |
185 | default: | |
186 | if (EVP_CIPHER_is_a(c, "CHACHA20-POLY1305")) { | |
187 | taglen = EVP_CHACHAPOLY_TLS_TAG_LEN; | |
188 | } else { | |
189 | /* MAC secret size corresponds to the MAC output size */ | |
190 | taglen = s->s3.tmp.new_mac_secret_size; | |
191 | } | |
192 | break; | |
cc110a0a MC |
193 | } |
194 | ||
aedbb71b | 195 | if (which & SSL3_CC_READ) { |
7f2f0ac7 MC |
196 | if (s->ext.use_etm) |
197 | s->s3.flags |= TLS1_FLAGS_ENCRYPT_THEN_MAC_READ; | |
198 | else | |
199 | s->s3.flags &= ~TLS1_FLAGS_ENCRYPT_THEN_MAC_READ; | |
aedbb71b | 200 | |
7f2f0ac7 MC |
201 | if (s->s3.tmp.new_cipher->algorithm2 & TLS1_STREAM_MAC) |
202 | s->mac_flags |= SSL_MAC_FLAG_READ_MAC_STREAM; | |
203 | else | |
204 | s->mac_flags &= ~SSL_MAC_FLAG_READ_MAC_STREAM; | |
aedbb71b | 205 | |
7f2f0ac7 MC |
206 | if (s->s3.tmp.new_cipher->algorithm2 & TLS1_TLSTREE) |
207 | s->mac_flags |= SSL_MAC_FLAG_READ_MAC_TLSTREE; | |
208 | else | |
209 | s->mac_flags &= ~SSL_MAC_FLAG_READ_MAC_TLSTREE; | |
aedbb71b | 210 | |
faa3e66c | 211 | direction = OSSL_RECORD_DIRECTION_READ; |
0f113f3e | 212 | } else { |
28a31a0a | 213 | if (s->ext.use_etm) |
555cbb32 | 214 | s->s3.flags |= TLS1_FLAGS_ENCRYPT_THEN_MAC_WRITE; |
28a31a0a | 215 | else |
555cbb32 | 216 | s->s3.flags &= ~TLS1_FLAGS_ENCRYPT_THEN_MAC_WRITE; |
28a31a0a | 217 | |
555cbb32 | 218 | if (s->s3.tmp.new_cipher->algorithm2 & TLS1_STREAM_MAC) |
0f113f3e MC |
219 | s->mac_flags |= SSL_MAC_FLAG_WRITE_MAC_STREAM; |
220 | else | |
221 | s->mac_flags &= ~SSL_MAC_FLAG_WRITE_MAC_STREAM; | |
5a5530a2 DB |
222 | |
223 | if (s->s3.tmp.new_cipher->algorithm2 & TLS1_TLSTREE) | |
224 | s->mac_flags |= SSL_MAC_FLAG_WRITE_MAC_TLSTREE; | |
225 | else | |
226 | s->mac_flags &= ~SSL_MAC_FLAG_WRITE_MAC_TLSTREE; | |
2b71b042 | 227 | |
faa3e66c | 228 | direction = OSSL_RECORD_DIRECTION_WRITE; |
0f113f3e | 229 | } |
49b26f54 | 230 | |
4897bd20 FWH |
231 | if (SSL_CONNECTION_IS_DTLS(s)) |
232 | dtls1_increment_epoch(s, which); | |
233 | ||
faa3e66c MC |
234 | if (!ssl_set_new_record_layer(s, s->version, direction, |
235 | OSSL_RECORD_PROTECTION_LEVEL_APPLICATION, | |
3f9175c7 | 236 | NULL, 0, key, cl, iv, (size_t)k, mac_secret, |
faa3e66c | 237 | mac_secret_size, c, taglen, mac_type, |
3f9175c7 | 238 | m, comp, NULL)) { |
b5588178 MC |
239 | /* SSLfatal already called */ |
240 | goto err; | |
524cb684 | 241 | } |
b5588178 | 242 | |
49b26f54 RL |
243 | OSSL_TRACE_BEGIN(TLS) { |
244 | BIO_printf(trc_out, "which = %04X, key:\n", which); | |
ed576acd | 245 | BIO_dump_indent(trc_out, key, EVP_CIPHER_get_key_length(c), 4); |
49b26f54 RL |
246 | BIO_printf(trc_out, "iv:\n"); |
247 | BIO_dump_indent(trc_out, iv, k, 4); | |
248 | } OSSL_TRACE_END(TLS); | |
58964a49 | 249 | |
208fb891 | 250 | return 1; |
0f113f3e | 251 | err: |
26a7d938 | 252 | return 0; |
0f113f3e | 253 | } |
58964a49 | 254 | |
38b051a1 | 255 | int tls1_setup_key_block(SSL_CONNECTION *s) |
0f113f3e | 256 | { |
b7d60e76 | 257 | unsigned char *p; |
0f113f3e MC |
258 | const EVP_CIPHER *c; |
259 | const EVP_MD *hash; | |
0f113f3e | 260 | SSL_COMP *comp; |
8c1a5343 MC |
261 | int mac_type = NID_undef; |
262 | size_t num, mac_secret_size = 0; | |
0f113f3e | 263 | int ret = 0; |
cc110a0a | 264 | int ivlen; |
58964a49 | 265 | |
555cbb32 | 266 | if (s->s3.tmp.key_block_length != 0) |
208fb891 | 267 | return 1; |
0f113f3e | 268 | |
38b051a1 TM |
269 | if (!ssl_cipher_get_evp(SSL_CONNECTION_GET_CTX(s), s->session, &c, &hash, |
270 | &mac_type, &mac_secret_size, &comp, | |
271 | s->ext.use_etm)) { | |
5a2d0ef3 RL |
272 | /* Error is already recorded */ |
273 | SSLfatal_alert(s, SSL_AD_INTERNAL_ERROR); | |
26a7d938 | 274 | return 0; |
0f113f3e MC |
275 | } |
276 | ||
c8f6c28a | 277 | ssl_evp_cipher_free(s->s3.tmp.new_sym_enc); |
555cbb32 | 278 | s->s3.tmp.new_sym_enc = c; |
c8f6c28a | 279 | ssl_evp_md_free(s->s3.tmp.new_hash); |
555cbb32 TS |
280 | s->s3.tmp.new_hash = hash; |
281 | s->s3.tmp.new_mac_pkey_type = mac_type; | |
282 | s->s3.tmp.new_mac_secret_size = mac_secret_size; | |
cc110a0a MC |
283 | ivlen = tls_iv_length_within_key_block(c); |
284 | if (ivlen < 0) { | |
285 | SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); | |
286 | return 0; | |
287 | } | |
288 | num = mac_secret_size + EVP_CIPHER_get_key_length(c) + ivlen; | |
0f113f3e MC |
289 | num *= 2; |
290 | ||
291 | ssl3_cleanup_key_block(s); | |
292 | ||
b7d60e76 | 293 | if ((p = OPENSSL_malloc(num)) == NULL) { |
e077455e | 294 | SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_CRYPTO_LIB); |
0f113f3e MC |
295 | goto err; |
296 | } | |
297 | ||
555cbb32 TS |
298 | s->s3.tmp.key_block_length = num; |
299 | s->s3.tmp.key_block = p; | |
0f113f3e | 300 | |
49b26f54 | 301 | OSSL_TRACE_BEGIN(TLS) { |
234261f3 | 302 | BIO_printf(trc_out, "key block length: %zu\n", num); |
49b26f54 | 303 | BIO_printf(trc_out, "client random\n"); |
555cbb32 | 304 | BIO_dump_indent(trc_out, s->s3.client_random, SSL3_RANDOM_SIZE, 4); |
49b26f54 | 305 | BIO_printf(trc_out, "server random\n"); |
555cbb32 | 306 | BIO_dump_indent(trc_out, s->s3.server_random, SSL3_RANDOM_SIZE, 4); |
49b26f54 RL |
307 | BIO_printf(trc_out, "master key\n"); |
308 | BIO_dump_indent(trc_out, | |
309 | s->session->master_key, | |
310 | s->session->master_key_length, 4); | |
311 | } OSSL_TRACE_END(TLS); | |
312 | ||
d4d2f3a4 MC |
313 | if (!tls1_generate_key_block(s, p, num)) { |
314 | /* SSLfatal() already called */ | |
0f113f3e | 315 | goto err; |
d4d2f3a4 | 316 | } |
49b26f54 RL |
317 | |
318 | OSSL_TRACE_BEGIN(TLS) { | |
319 | BIO_printf(trc_out, "key block\n"); | |
320 | BIO_dump_indent(trc_out, p, num, 4); | |
321 | } OSSL_TRACE_END(TLS); | |
58964a49 | 322 | |
0f113f3e MC |
323 | ret = 1; |
324 | err: | |
26a7d938 | 325 | return ret; |
0f113f3e | 326 | } |
58964a49 | 327 | |
38b051a1 TM |
328 | size_t tls1_final_finish_mac(SSL_CONNECTION *s, const char *str, |
329 | size_t slen, unsigned char *out) | |
0f113f3e | 330 | { |
8c1a5343 | 331 | size_t hashlen; |
28ba2541 | 332 | unsigned char hash[EVP_MAX_MD_SIZE]; |
5a5530a2 DB |
333 | size_t finished_size = TLS1_FINISH_MAC_LENGTH; |
334 | ||
335 | if (s->s3.tmp.new_cipher->algorithm_mkey & SSL_kGOST18) | |
336 | finished_size = 32; | |
0f113f3e | 337 | |
d4d2f3a4 MC |
338 | if (!ssl3_digest_cached_records(s, 0)) { |
339 | /* SSLfatal() already called */ | |
124037fd | 340 | return 0; |
d4d2f3a4 | 341 | } |
0f113f3e | 342 | |
d4d2f3a4 MC |
343 | if (!ssl_handshake_hash(s, hash, sizeof(hash), &hashlen)) { |
344 | /* SSLfatal() already called */ | |
48fbcbac | 345 | return 0; |
d4d2f3a4 | 346 | } |
0f113f3e | 347 | |
b7d60e76 | 348 | if (!tls1_PRF(s, str, slen, hash, hashlen, NULL, 0, NULL, 0, NULL, 0, |
0f113f3e | 349 | s->session->master_key, s->session->master_key_length, |
5a5530a2 | 350 | out, finished_size, 1)) { |
d4d2f3a4 | 351 | /* SSLfatal() already called */ |
0f113f3e | 352 | return 0; |
d4d2f3a4 | 353 | } |
c9dd49a7 | 354 | OPENSSL_cleanse(hash, hashlen); |
5a5530a2 | 355 | return finished_size; |
0f113f3e | 356 | } |
58964a49 | 357 | |
38b051a1 TM |
358 | int tls1_generate_master_secret(SSL_CONNECTION *s, unsigned char *out, |
359 | unsigned char *p, size_t len, | |
360 | size_t *secret_size) | |
0f113f3e | 361 | { |
329114f9 | 362 | if (s->session->flags & SSL_SESS_FLAG_EXTMS) { |
0cfb0e75 | 363 | unsigned char hash[EVP_MAX_MD_SIZE * 2]; |
8c1a5343 | 364 | size_t hashlen; |
a230b26e | 365 | /* |
79c44b4e | 366 | * Digest cached records keeping record buffer (if present): this won't |
a230b26e EK |
367 | * affect client auth because we're freezing the buffer at the same |
368 | * point (after client key exchange and before certificate verify) | |
124037fd | 369 | */ |
f63a17d6 MC |
370 | if (!ssl3_digest_cached_records(s, 1) |
371 | || !ssl_handshake_hash(s, hash, sizeof(hash), &hashlen)) { | |
372 | /* SSLfatal() already called */ | |
8c1a5343 | 373 | return 0; |
f63a17d6 | 374 | } |
49b26f54 RL |
375 | OSSL_TRACE_BEGIN(TLS) { |
376 | BIO_printf(trc_out, "Handshake hashes:\n"); | |
377 | BIO_dump(trc_out, (char *)hash, hashlen); | |
378 | } OSSL_TRACE_END(TLS); | |
d4d2f3a4 MC |
379 | if (!tls1_PRF(s, |
380 | TLS_MD_EXTENDED_MASTER_SECRET_CONST, | |
381 | TLS_MD_EXTENDED_MASTER_SECRET_CONST_SIZE, | |
382 | hash, hashlen, | |
383 | NULL, 0, | |
384 | NULL, 0, | |
385 | NULL, 0, p, len, out, | |
386 | SSL3_MASTER_SECRET_SIZE, 1)) { | |
387 | /* SSLfatal() already called */ | |
388 | return 0; | |
389 | } | |
0cfb0e75 DSH |
390 | OPENSSL_cleanse(hash, hashlen); |
391 | } else { | |
d4d2f3a4 MC |
392 | if (!tls1_PRF(s, |
393 | TLS_MD_MASTER_SECRET_CONST, | |
394 | TLS_MD_MASTER_SECRET_CONST_SIZE, | |
555cbb32 | 395 | s->s3.client_random, SSL3_RANDOM_SIZE, |
d4d2f3a4 | 396 | NULL, 0, |
555cbb32 | 397 | s->s3.server_random, SSL3_RANDOM_SIZE, |
d4d2f3a4 MC |
398 | NULL, 0, p, len, out, |
399 | SSL3_MASTER_SECRET_SIZE, 1)) { | |
400 | /* SSLfatal() already called */ | |
401 | return 0; | |
402 | } | |
0cfb0e75 | 403 | } |
49b26f54 RL |
404 | |
405 | OSSL_TRACE_BEGIN(TLS) { | |
406 | BIO_printf(trc_out, "Premaster Secret:\n"); | |
407 | BIO_dump_indent(trc_out, p, len, 4); | |
408 | BIO_printf(trc_out, "Client Random:\n"); | |
555cbb32 | 409 | BIO_dump_indent(trc_out, s->s3.client_random, SSL3_RANDOM_SIZE, 4); |
49b26f54 | 410 | BIO_printf(trc_out, "Server Random:\n"); |
555cbb32 | 411 | BIO_dump_indent(trc_out, s->s3.server_random, SSL3_RANDOM_SIZE, 4); |
49b26f54 RL |
412 | BIO_printf(trc_out, "Master Secret:\n"); |
413 | BIO_dump_indent(trc_out, | |
414 | s->session->master_key, | |
415 | SSL3_MASTER_SECRET_SIZE, 4); | |
416 | } OSSL_TRACE_END(TLS); | |
761772d7 | 417 | |
8c1a5343 MC |
418 | *secret_size = SSL3_MASTER_SECRET_SIZE; |
419 | return 1; | |
0f113f3e | 420 | } |
58964a49 | 421 | |
38b051a1 TM |
422 | int tls1_export_keying_material(SSL_CONNECTION *s, unsigned char *out, |
423 | size_t olen, const char *label, size_t llen, | |
0f113f3e MC |
424 | const unsigned char *context, |
425 | size_t contextlen, int use_context) | |
426 | { | |
0f113f3e | 427 | unsigned char *val = NULL; |
1c8a527c | 428 | size_t vallen = 0, currentvalpos; |
e077455e | 429 | int rv = 0; |
e0af0405 | 430 | |
ef9d8f2f DU |
431 | /* |
432 | * RFC 5705 embeds context length as uint16; reject longer context | |
433 | * before proceeding. | |
434 | */ | |
435 | if (contextlen > 0xffff) { | |
436 | ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT); | |
437 | return 0; | |
438 | } | |
439 | ||
0f113f3e MC |
440 | /* |
441 | * construct PRF arguments we construct the PRF argument ourself rather | |
442 | * than passing separate values into the TLS PRF to ensure that the | |
443 | * concatenation of values does not create a prohibited label. | |
444 | */ | |
445 | vallen = llen + SSL3_RANDOM_SIZE * 2; | |
446 | if (use_context) { | |
447 | vallen += 2 + contextlen; | |
448 | } | |
449 | ||
450 | val = OPENSSL_malloc(vallen); | |
451 | if (val == NULL) | |
e077455e | 452 | goto ret; |
0f113f3e MC |
453 | currentvalpos = 0; |
454 | memcpy(val + currentvalpos, (unsigned char *)label, llen); | |
455 | currentvalpos += llen; | |
555cbb32 | 456 | memcpy(val + currentvalpos, s->s3.client_random, SSL3_RANDOM_SIZE); |
0f113f3e | 457 | currentvalpos += SSL3_RANDOM_SIZE; |
555cbb32 | 458 | memcpy(val + currentvalpos, s->s3.server_random, SSL3_RANDOM_SIZE); |
0f113f3e MC |
459 | currentvalpos += SSL3_RANDOM_SIZE; |
460 | ||
461 | if (use_context) { | |
462 | val[currentvalpos] = (contextlen >> 8) & 0xff; | |
463 | currentvalpos++; | |
464 | val[currentvalpos] = contextlen & 0xff; | |
465 | currentvalpos++; | |
466 | if ((contextlen > 0) || (context != NULL)) { | |
467 | memcpy(val + currentvalpos, context, contextlen); | |
468 | } | |
469 | } | |
470 | ||
471 | /* | |
472 | * disallow prohibited labels note that SSL3_RANDOM_SIZE > max(prohibited | |
473 | * label len) = 15, so size of val > max(prohibited label len) = 15 and | |
474 | * the comparisons won't have buffer overflow | |
475 | */ | |
476 | if (memcmp(val, TLS_MD_CLIENT_FINISH_CONST, | |
477 | TLS_MD_CLIENT_FINISH_CONST_SIZE) == 0) | |
478 | goto err1; | |
479 | if (memcmp(val, TLS_MD_SERVER_FINISH_CONST, | |
480 | TLS_MD_SERVER_FINISH_CONST_SIZE) == 0) | |
481 | goto err1; | |
482 | if (memcmp(val, TLS_MD_MASTER_SECRET_CONST, | |
483 | TLS_MD_MASTER_SECRET_CONST_SIZE) == 0) | |
484 | goto err1; | |
0cfb0e75 DSH |
485 | if (memcmp(val, TLS_MD_EXTENDED_MASTER_SECRET_CONST, |
486 | TLS_MD_EXTENDED_MASTER_SECRET_CONST_SIZE) == 0) | |
487 | goto err1; | |
0f113f3e MC |
488 | if (memcmp(val, TLS_MD_KEY_EXPANSION_CONST, |
489 | TLS_MD_KEY_EXPANSION_CONST_SIZE) == 0) | |
490 | goto err1; | |
491 | ||
28ba2541 | 492 | rv = tls1_PRF(s, |
0f113f3e MC |
493 | val, vallen, |
494 | NULL, 0, | |
495 | NULL, 0, | |
496 | NULL, 0, | |
497 | NULL, 0, | |
498 | s->session->master_key, s->session->master_key_length, | |
d4d2f3a4 | 499 | out, olen, 0); |
e0af0405 | 500 | |
0f113f3e MC |
501 | goto ret; |
502 | err1: | |
6849b73c | 503 | ERR_raise(ERR_LIB_SSL, SSL_R_TLS_ILLEGAL_EXPORTER_LABEL); |
0f113f3e | 504 | ret: |
05c7b163 | 505 | OPENSSL_clear_free(val, vallen); |
26a7d938 | 506 | return rv; |
0f113f3e | 507 | } |
e0af0405 | 508 | |
6b691a5c | 509 | int tls1_alert_code(int code) |
0f113f3e MC |
510 | { |
511 | switch (code) { | |
512 | case SSL_AD_CLOSE_NOTIFY: | |
26a7d938 | 513 | return SSL3_AD_CLOSE_NOTIFY; |
0f113f3e | 514 | case SSL_AD_UNEXPECTED_MESSAGE: |
26a7d938 | 515 | return SSL3_AD_UNEXPECTED_MESSAGE; |
0f113f3e | 516 | case SSL_AD_BAD_RECORD_MAC: |
26a7d938 | 517 | return SSL3_AD_BAD_RECORD_MAC; |
0f113f3e | 518 | case SSL_AD_DECRYPTION_FAILED: |
26a7d938 | 519 | return TLS1_AD_DECRYPTION_FAILED; |
0f113f3e | 520 | case SSL_AD_RECORD_OVERFLOW: |
26a7d938 | 521 | return TLS1_AD_RECORD_OVERFLOW; |
0f113f3e | 522 | case SSL_AD_DECOMPRESSION_FAILURE: |
26a7d938 | 523 | return SSL3_AD_DECOMPRESSION_FAILURE; |
0f113f3e | 524 | case SSL_AD_HANDSHAKE_FAILURE: |
26a7d938 | 525 | return SSL3_AD_HANDSHAKE_FAILURE; |
0f113f3e | 526 | case SSL_AD_NO_CERTIFICATE: |
26a7d938 | 527 | return -1; |
0f113f3e | 528 | case SSL_AD_BAD_CERTIFICATE: |
26a7d938 | 529 | return SSL3_AD_BAD_CERTIFICATE; |
0f113f3e | 530 | case SSL_AD_UNSUPPORTED_CERTIFICATE: |
26a7d938 | 531 | return SSL3_AD_UNSUPPORTED_CERTIFICATE; |
0f113f3e | 532 | case SSL_AD_CERTIFICATE_REVOKED: |
26a7d938 | 533 | return SSL3_AD_CERTIFICATE_REVOKED; |
0f113f3e | 534 | case SSL_AD_CERTIFICATE_EXPIRED: |
26a7d938 | 535 | return SSL3_AD_CERTIFICATE_EXPIRED; |
0f113f3e | 536 | case SSL_AD_CERTIFICATE_UNKNOWN: |
26a7d938 | 537 | return SSL3_AD_CERTIFICATE_UNKNOWN; |
0f113f3e | 538 | case SSL_AD_ILLEGAL_PARAMETER: |
26a7d938 | 539 | return SSL3_AD_ILLEGAL_PARAMETER; |
0f113f3e | 540 | case SSL_AD_UNKNOWN_CA: |
26a7d938 | 541 | return TLS1_AD_UNKNOWN_CA; |
0f113f3e | 542 | case SSL_AD_ACCESS_DENIED: |
26a7d938 | 543 | return TLS1_AD_ACCESS_DENIED; |
0f113f3e | 544 | case SSL_AD_DECODE_ERROR: |
26a7d938 | 545 | return TLS1_AD_DECODE_ERROR; |
0f113f3e | 546 | case SSL_AD_DECRYPT_ERROR: |
26a7d938 | 547 | return TLS1_AD_DECRYPT_ERROR; |
0f113f3e | 548 | case SSL_AD_EXPORT_RESTRICTION: |
26a7d938 | 549 | return TLS1_AD_EXPORT_RESTRICTION; |
0f113f3e | 550 | case SSL_AD_PROTOCOL_VERSION: |
26a7d938 | 551 | return TLS1_AD_PROTOCOL_VERSION; |
0f113f3e | 552 | case SSL_AD_INSUFFICIENT_SECURITY: |
26a7d938 | 553 | return TLS1_AD_INSUFFICIENT_SECURITY; |
0f113f3e | 554 | case SSL_AD_INTERNAL_ERROR: |
26a7d938 | 555 | return TLS1_AD_INTERNAL_ERROR; |
0f113f3e | 556 | case SSL_AD_USER_CANCELLED: |
26a7d938 | 557 | return TLS1_AD_USER_CANCELLED; |
0f113f3e | 558 | case SSL_AD_NO_RENEGOTIATION: |
26a7d938 | 559 | return TLS1_AD_NO_RENEGOTIATION; |
0f113f3e | 560 | case SSL_AD_UNSUPPORTED_EXTENSION: |
26a7d938 | 561 | return TLS1_AD_UNSUPPORTED_EXTENSION; |
0f113f3e | 562 | case SSL_AD_CERTIFICATE_UNOBTAINABLE: |
26a7d938 | 563 | return TLS1_AD_CERTIFICATE_UNOBTAINABLE; |
0f113f3e | 564 | case SSL_AD_UNRECOGNIZED_NAME: |
26a7d938 | 565 | return TLS1_AD_UNRECOGNIZED_NAME; |
0f113f3e | 566 | case SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE: |
26a7d938 | 567 | return TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE; |
0f113f3e | 568 | case SSL_AD_BAD_CERTIFICATE_HASH_VALUE: |
26a7d938 | 569 | return TLS1_AD_BAD_CERTIFICATE_HASH_VALUE; |
0f113f3e | 570 | case SSL_AD_UNKNOWN_PSK_IDENTITY: |
26a7d938 | 571 | return TLS1_AD_UNKNOWN_PSK_IDENTITY; |
0f113f3e | 572 | case SSL_AD_INAPPROPRIATE_FALLBACK: |
26a7d938 | 573 | return TLS1_AD_INAPPROPRIATE_FALLBACK; |
06217867 | 574 | case SSL_AD_NO_APPLICATION_PROTOCOL: |
26a7d938 | 575 | return TLS1_AD_NO_APPLICATION_PROTOCOL; |
42c28b63 MC |
576 | case SSL_AD_CERTIFICATE_REQUIRED: |
577 | return SSL_AD_HANDSHAKE_FAILURE; | |
1376708c BK |
578 | case TLS13_AD_MISSING_EXTENSION: |
579 | return SSL_AD_HANDSHAKE_FAILURE; | |
0f113f3e | 580 | default: |
26a7d938 | 581 | return -1; |
0f113f3e MC |
582 | } |
583 | } |