diff options
Diffstat (limited to '')
-rw-r--r-- | src/lib/libssl/tls12_key_schedule.c | 291 |
1 files changed, 0 insertions, 291 deletions
diff --git a/src/lib/libssl/tls12_key_schedule.c b/src/lib/libssl/tls12_key_schedule.c deleted file mode 100644 index 1ac003329e..0000000000 --- a/src/lib/libssl/tls12_key_schedule.c +++ /dev/null | |||
@@ -1,291 +0,0 @@ | |||
1 | /* $OpenBSD: tls12_key_schedule.c,v 1.4 2024/02/03 15:58:34 beck Exp $ */ | ||
2 | /* | ||
3 | * Copyright (c) 2021 Joel Sing <jsing@openbsd.org> | ||
4 | * | ||
5 | * Permission to use, copy, modify, and distribute this software for any | ||
6 | * purpose with or without fee is hereby granted, provided that the above | ||
7 | * copyright notice and this permission notice appear in all copies. | ||
8 | * | ||
9 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
10 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
11 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
12 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
13 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
14 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
15 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
16 | */ | ||
17 | |||
18 | #include <stdlib.h> | ||
19 | |||
20 | #include <openssl/evp.h> | ||
21 | |||
22 | #include "bytestring.h" | ||
23 | #include "ssl_local.h" | ||
24 | #include "tls12_internal.h" | ||
25 | |||
26 | struct tls12_key_block { | ||
27 | CBS client_write_mac_key; | ||
28 | CBS server_write_mac_key; | ||
29 | CBS client_write_key; | ||
30 | CBS server_write_key; | ||
31 | CBS client_write_iv; | ||
32 | CBS server_write_iv; | ||
33 | |||
34 | uint8_t *key_block; | ||
35 | size_t key_block_len; | ||
36 | }; | ||
37 | |||
38 | struct tls12_key_block * | ||
39 | tls12_key_block_new(void) | ||
40 | { | ||
41 | return calloc(1, sizeof(struct tls12_key_block)); | ||
42 | } | ||
43 | |||
44 | static void | ||
45 | tls12_key_block_clear(struct tls12_key_block *kb) | ||
46 | { | ||
47 | CBS_init(&kb->client_write_mac_key, NULL, 0); | ||
48 | CBS_init(&kb->server_write_mac_key, NULL, 0); | ||
49 | CBS_init(&kb->client_write_key, NULL, 0); | ||
50 | CBS_init(&kb->server_write_key, NULL, 0); | ||
51 | CBS_init(&kb->client_write_iv, NULL, 0); | ||
52 | CBS_init(&kb->server_write_iv, NULL, 0); | ||
53 | |||
54 | freezero(kb->key_block, kb->key_block_len); | ||
55 | kb->key_block = NULL; | ||
56 | kb->key_block_len = 0; | ||
57 | } | ||
58 | |||
59 | void | ||
60 | tls12_key_block_free(struct tls12_key_block *kb) | ||
61 | { | ||
62 | if (kb == NULL) | ||
63 | return; | ||
64 | |||
65 | tls12_key_block_clear(kb); | ||
66 | |||
67 | freezero(kb, sizeof(struct tls12_key_block)); | ||
68 | } | ||
69 | |||
70 | void | ||
71 | tls12_key_block_client_write(struct tls12_key_block *kb, CBS *mac_key, | ||
72 | CBS *key, CBS *iv) | ||
73 | { | ||
74 | CBS_dup(&kb->client_write_mac_key, mac_key); | ||
75 | CBS_dup(&kb->client_write_key, key); | ||
76 | CBS_dup(&kb->client_write_iv, iv); | ||
77 | } | ||
78 | |||
79 | void | ||
80 | tls12_key_block_server_write(struct tls12_key_block *kb, CBS *mac_key, | ||
81 | CBS *key, CBS *iv) | ||
82 | { | ||
83 | CBS_dup(&kb->server_write_mac_key, mac_key); | ||
84 | CBS_dup(&kb->server_write_key, key); | ||
85 | CBS_dup(&kb->server_write_iv, iv); | ||
86 | } | ||
87 | |||
88 | int | ||
89 | tls12_key_block_generate(struct tls12_key_block *kb, SSL *s, | ||
90 | const EVP_AEAD *aead, const EVP_CIPHER *cipher, const EVP_MD *mac_hash) | ||
91 | { | ||
92 | size_t mac_key_len = 0, key_len = 0, iv_len = 0; | ||
93 | uint8_t *key_block = NULL; | ||
94 | size_t key_block_len = 0; | ||
95 | CBS cbs; | ||
96 | |||
97 | /* | ||
98 | * Generate a TLSv1.2 key block and partition into individual secrets, | ||
99 | * as per RFC 5246 section 6.3. | ||
100 | */ | ||
101 | |||
102 | tls12_key_block_clear(kb); | ||
103 | |||
104 | /* Must have AEAD or cipher/MAC pair. */ | ||
105 | if (aead == NULL && (cipher == NULL || mac_hash == NULL)) | ||
106 | goto err; | ||
107 | |||
108 | if (aead != NULL) { | ||
109 | key_len = EVP_AEAD_key_length(aead); | ||
110 | |||
111 | /* AEAD fixed nonce length. */ | ||
112 | if (aead == EVP_aead_aes_128_gcm() || | ||
113 | aead == EVP_aead_aes_256_gcm()) | ||
114 | iv_len = 4; | ||
115 | else if (aead == EVP_aead_chacha20_poly1305()) | ||
116 | iv_len = 12; | ||
117 | else | ||
118 | goto err; | ||
119 | } else if (cipher != NULL && mac_hash != NULL) { | ||
120 | /* | ||
121 | * A negative integer return value will be detected via the | ||
122 | * EVP_MAX_* checks against the size_t variables below. | ||
123 | */ | ||
124 | mac_key_len = EVP_MD_size(mac_hash); | ||
125 | key_len = EVP_CIPHER_key_length(cipher); | ||
126 | iv_len = EVP_CIPHER_iv_length(cipher); | ||
127 | } | ||
128 | |||
129 | if (mac_key_len > EVP_MAX_MD_SIZE) | ||
130 | goto err; | ||
131 | if (key_len > EVP_MAX_KEY_LENGTH) | ||
132 | goto err; | ||
133 | if (iv_len > EVP_MAX_IV_LENGTH) | ||
134 | goto err; | ||
135 | |||
136 | key_block_len = 2 * mac_key_len + 2 * key_len + 2 * iv_len; | ||
137 | if ((key_block = calloc(1, key_block_len)) == NULL) | ||
138 | goto err; | ||
139 | |||
140 | if (!tls1_generate_key_block(s, key_block, key_block_len)) | ||
141 | goto err; | ||
142 | |||
143 | kb->key_block = key_block; | ||
144 | kb->key_block_len = key_block_len; | ||
145 | key_block = NULL; | ||
146 | key_block_len = 0; | ||
147 | |||
148 | /* Partition key block into individual secrets. */ | ||
149 | CBS_init(&cbs, kb->key_block, kb->key_block_len); | ||
150 | if (!CBS_get_bytes(&cbs, &kb->client_write_mac_key, mac_key_len)) | ||
151 | goto err; | ||
152 | if (!CBS_get_bytes(&cbs, &kb->server_write_mac_key, mac_key_len)) | ||
153 | goto err; | ||
154 | if (!CBS_get_bytes(&cbs, &kb->client_write_key, key_len)) | ||
155 | goto err; | ||
156 | if (!CBS_get_bytes(&cbs, &kb->server_write_key, key_len)) | ||
157 | goto err; | ||
158 | if (!CBS_get_bytes(&cbs, &kb->client_write_iv, iv_len)) | ||
159 | goto err; | ||
160 | if (!CBS_get_bytes(&cbs, &kb->server_write_iv, iv_len)) | ||
161 | goto err; | ||
162 | if (CBS_len(&cbs) != 0) | ||
163 | goto err; | ||
164 | |||
165 | return 1; | ||
166 | |||
167 | err: | ||
168 | tls12_key_block_clear(kb); | ||
169 | freezero(key_block, key_block_len); | ||
170 | |||
171 | return 0; | ||
172 | } | ||
173 | |||
174 | struct tls12_reserved_label { | ||
175 | const char *label; | ||
176 | size_t label_len; | ||
177 | }; | ||
178 | |||
179 | /* | ||
180 | * RFC 5705 section 6. | ||
181 | */ | ||
182 | static const struct tls12_reserved_label tls12_reserved_labels[] = { | ||
183 | { | ||
184 | .label = TLS_MD_CLIENT_FINISH_CONST, | ||
185 | .label_len = TLS_MD_CLIENT_FINISH_CONST_SIZE, | ||
186 | }, | ||
187 | { | ||
188 | .label = TLS_MD_SERVER_FINISH_CONST, | ||
189 | .label_len = TLS_MD_SERVER_FINISH_CONST_SIZE, | ||
190 | }, | ||
191 | { | ||
192 | .label = TLS_MD_MASTER_SECRET_CONST, | ||
193 | .label_len = TLS_MD_MASTER_SECRET_CONST_SIZE, | ||
194 | }, | ||
195 | { | ||
196 | .label = TLS_MD_KEY_EXPANSION_CONST, | ||
197 | .label_len = TLS_MD_KEY_EXPANSION_CONST_SIZE, | ||
198 | }, | ||
199 | { | ||
200 | .label = NULL, | ||
201 | .label_len = 0, | ||
202 | }, | ||
203 | }; | ||
204 | |||
205 | int | ||
206 | tls12_exporter(SSL *s, const uint8_t *label, size_t label_len, | ||
207 | const uint8_t *context_value, size_t context_value_len, int use_context, | ||
208 | uint8_t *out, size_t out_len) | ||
209 | { | ||
210 | uint8_t *data = NULL; | ||
211 | size_t data_len = 0; | ||
212 | CBB cbb, context; | ||
213 | CBS seed; | ||
214 | size_t i; | ||
215 | int ret = 0; | ||
216 | |||
217 | /* | ||
218 | * RFC 5705 - Key Material Exporters for TLS. | ||
219 | */ | ||
220 | |||
221 | memset(&cbb, 0, sizeof(cbb)); | ||
222 | |||
223 | if (!SSL_is_init_finished(s)) { | ||
224 | SSLerror(s, SSL_R_BAD_STATE); | ||
225 | goto err; | ||
226 | } | ||
227 | |||
228 | if (s->s3->hs.negotiated_tls_version >= TLS1_3_VERSION) | ||
229 | goto err; | ||
230 | |||
231 | /* | ||
232 | * Due to exceptional design choices, we need to build a concatenation | ||
233 | * of the label and the seed value, before checking for reserved | ||
234 | * labels. This prevents a reserved label from being split across the | ||
235 | * label and the seed (that includes the client random), which are | ||
236 | * concatenated by the PRF. | ||
237 | */ | ||
238 | if (!CBB_init(&cbb, 0)) | ||
239 | goto err; | ||
240 | if (!CBB_add_bytes(&cbb, label, label_len)) | ||
241 | goto err; | ||
242 | if (!CBB_add_bytes(&cbb, s->s3->client_random, SSL3_RANDOM_SIZE)) | ||
243 | goto err; | ||
244 | if (!CBB_add_bytes(&cbb, s->s3->server_random, SSL3_RANDOM_SIZE)) | ||
245 | goto err; | ||
246 | if (use_context) { | ||
247 | if (!CBB_add_u16_length_prefixed(&cbb, &context)) | ||
248 | goto err; | ||
249 | if (context_value_len > 0) { | ||
250 | if (!CBB_add_bytes(&context, context_value, | ||
251 | context_value_len)) | ||
252 | goto err; | ||
253 | } | ||
254 | } | ||
255 | if (!CBB_finish(&cbb, &data, &data_len)) | ||
256 | goto err; | ||
257 | |||
258 | /* | ||
259 | * Ensure that the block (label + seed) does not start with a reserved | ||
260 | * label - in an ideal world we would ensure that the label has an | ||
261 | * explicitly permitted prefix instead, but of course this also got | ||
262 | * messed up by the standards. | ||
263 | */ | ||
264 | for (i = 0; tls12_reserved_labels[i].label != NULL; i++) { | ||
265 | /* XXX - consider adding/using CBS_has_prefix(). */ | ||
266 | if (tls12_reserved_labels[i].label_len > data_len) | ||
267 | goto err; | ||
268 | if (memcmp(data, tls12_reserved_labels[i].label, | ||
269 | tls12_reserved_labels[i].label_len) == 0) { | ||
270 | SSLerror(s, SSL_R_TLS_ILLEGAL_EXPORTER_LABEL); | ||
271 | goto err; | ||
272 | } | ||
273 | } | ||
274 | |||
275 | CBS_init(&seed, data, data_len); | ||
276 | if (!CBS_skip(&seed, label_len)) | ||
277 | goto err; | ||
278 | |||
279 | if (!tls1_PRF(s, s->session->master_key, s->session->master_key_length, | ||
280 | label, label_len, CBS_data(&seed), CBS_len(&seed), NULL, 0, NULL, 0, | ||
281 | NULL, 0, out, out_len)) | ||
282 | goto err; | ||
283 | |||
284 | ret = 1; | ||
285 | |||
286 | err: | ||
287 | freezero(data, data_len); | ||
288 | CBB_cleanup(&cbb); | ||
289 | |||
290 | return ret; | ||
291 | } | ||