summaryrefslogtreecommitdiff
path: root/src/lib/libssl/tls12_key_schedule.c
diff options
context:
space:
mode:
authorjsing <>2022-11-07 11:58:45 +0000
committerjsing <>2022-11-07 11:58:45 +0000
commit9b1a5502ac166e7ddd3da7c143bb65686a035ac4 (patch)
treebfa8daa6e7b625129ae066d13e602b42c3262e43 /src/lib/libssl/tls12_key_schedule.c
parent7aa564fe60027590616687055794c45960ec44dd (diff)
downloadopenbsd-9b1a5502ac166e7ddd3da7c143bb65686a035ac4.tar.gz
openbsd-9b1a5502ac166e7ddd3da7c143bb65686a035ac4.tar.bz2
openbsd-9b1a5502ac166e7ddd3da7c143bb65686a035ac4.zip
Rewrite TLSv1.2 key exporter.
Replace the grotty TLSv1.2 key exporter with a cleaner version that uses CBB and CBS. ok tb@
Diffstat (limited to 'src/lib/libssl/tls12_key_schedule.c')
-rw-r--r--src/lib/libssl/tls12_key_schedule.c122
1 files changed, 121 insertions, 1 deletions
diff --git a/src/lib/libssl/tls12_key_schedule.c b/src/lib/libssl/tls12_key_schedule.c
index c206460d95..e603e2c222 100644
--- a/src/lib/libssl/tls12_key_schedule.c
+++ b/src/lib/libssl/tls12_key_schedule.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: tls12_key_schedule.c,v 1.1 2021/05/05 10:05:27 jsing Exp $ */ 1/* $OpenBSD: tls12_key_schedule.c,v 1.2 2022/11/07 11:58:45 jsing Exp $ */
2/* 2/*
3 * Copyright (c) 2021 Joel Sing <jsing@openbsd.org> 3 * Copyright (c) 2021 Joel Sing <jsing@openbsd.org>
4 * 4 *
@@ -21,6 +21,7 @@
21 21
22#include "bytestring.h" 22#include "bytestring.h"
23#include "ssl_locl.h" 23#include "ssl_locl.h"
24#include "tls12_internal.h"
24 25
25struct tls12_key_block { 26struct tls12_key_block {
26 CBS client_write_mac_key; 27 CBS client_write_mac_key;
@@ -173,3 +174,122 @@ tls12_key_block_generate(struct tls12_key_block *kb, SSL *s,
173 174
174 return 0; 175 return 0;
175} 176}
177
178struct tls12_reserved_label {
179 const char *label;
180 size_t label_len;
181};
182
183/*
184 * RFC 5705 section 6.
185 */
186static const struct tls12_reserved_label tls12_reserved_labels[] = {
187 {
188 .label = TLS_MD_CLIENT_FINISH_CONST,
189 .label_len = TLS_MD_CLIENT_FINISH_CONST_SIZE,
190 },
191 {
192 .label = TLS_MD_SERVER_FINISH_CONST,
193 .label_len = TLS_MD_SERVER_FINISH_CONST_SIZE,
194 },
195 {
196 .label = TLS_MD_MASTER_SECRET_CONST,
197 .label_len = TLS_MD_MASTER_SECRET_CONST_SIZE,
198 },
199 {
200 .label = TLS_MD_KEY_EXPANSION_CONST,
201 .label_len = TLS_MD_KEY_EXPANSION_CONST_SIZE,
202 },
203 {
204 .label = NULL,
205 .label_len = 0,
206 },
207};
208
209int
210tls12_exporter(SSL *s, const uint8_t *label, size_t label_len,
211 const uint8_t *context_value, size_t context_value_len, int use_context,
212 uint8_t *out, size_t out_len)
213{
214 uint8_t *data = NULL;
215 size_t data_len = 0;
216 CBB cbb, context;
217 CBS seed;
218 size_t i;
219 int ret = 0;
220
221 /*
222 * RFC 5705 - Key Material Exporters for TLS.
223 */
224
225 memset(&cbb, 0, sizeof(cbb));
226
227 if (!SSL_is_init_finished(s)) {
228 SSLerror(s, SSL_R_BAD_STATE);
229 goto err;
230 }
231
232 if (s->s3->hs.negotiated_tls_version >= TLS1_3_VERSION)
233 goto err;
234
235 /*
236 * Due to exceptional design choices, we need to build a concatenation
237 * of the label and the seed value, before checking for reserved
238 * labels. This prevents a reserved label from being split across the
239 * label and the seed (that includes the client random), which are
240 * concatenated by the PRF.
241 */
242 if (!CBB_init(&cbb, 0))
243 goto err;
244 if (!CBB_add_bytes(&cbb, label, label_len))
245 goto err;
246 if (!CBB_add_bytes(&cbb, s->s3->client_random, SSL3_RANDOM_SIZE))
247 goto err;
248 if (!CBB_add_bytes(&cbb, s->s3->server_random, SSL3_RANDOM_SIZE))
249 goto err;
250 if (use_context) {
251 if (!CBB_add_u16_length_prefixed(&cbb, &context))
252 goto err;
253 if (context_value_len > 0) {
254 if (!CBB_add_bytes(&context, context_value,
255 context_value_len))
256 goto err;
257 }
258 }
259 if (!CBB_finish(&cbb, &data, &data_len))
260 goto err;
261
262 /*
263 * Ensure that the block (label + seed) does not start with a reserved
264 * label - in an ideal world we would ensure that the label has an
265 * explicitly permitted prefix instead, but of course this also got
266 * messed up by the standards.
267 */
268 for (i = 0; tls12_reserved_labels[i].label != NULL; i++) {
269 /* XXX - consider adding/using CBS_has_prefix(). */
270 if (tls12_reserved_labels[i].label_len > data_len)
271 goto err;
272 if (memcmp(data, tls12_reserved_labels[i].label,
273 tls12_reserved_labels[i].label_len) == 0) {
274 SSLerror(s, SSL_R_TLS_ILLEGAL_EXPORTER_LABEL);
275 goto err;
276 }
277 }
278
279 CBS_init(&seed, data, data_len);
280 if (!CBS_skip(&seed, label_len))
281 goto err;
282
283 if (!tls1_PRF(s, s->session->master_key, s->session->master_key_length,
284 label, label_len, CBS_data(&seed), CBS_len(&seed), NULL, 0, NULL, 0,
285 NULL, 0, out, out_len))
286 goto err;
287
288 ret = 1;
289
290 err:
291 freezero(data, data_len);
292 CBB_cleanup(&cbb);
293
294 return ret;
295}