diff options
author | jsing <> | 2017-03-18 12:58:18 +0000 |
---|---|---|
committer | jsing <> | 2017-03-18 12:58:18 +0000 |
commit | 6c55a7efb3abec4388f94455e4f9a2ddd3bc326a (patch) | |
tree | 811759f0fd76d71b0bf1418a680206a95aa2d0e3 /src/lib | |
parent | 0bfcc4ad1918612e366e9eb010a9013e96a59986 (diff) | |
download | openbsd-6c55a7efb3abec4388f94455e4f9a2ddd3bc326a.tar.gz openbsd-6c55a7efb3abec4388f94455e4f9a2ddd3bc326a.tar.bz2 openbsd-6c55a7efb3abec4388f94455e4f9a2ddd3bc326a.zip |
Currently tls1_PRF() requires that a temporary buffer be provided, that
matches the size of the output buffer. This is used in the case where
there are multiple hashes - tls_P_hash() is called with the temporary
buffer and the result is then xored into the output buffer.
Avoid this by simply using a local buffer in tls_P_hash() and then xoring
the result into the output buffer. Overall this makes the code cleaner
and simplifies all of the tls_PRF() callers.
Similar to BoringSSL.
ok inoguchi@
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/libssl/t1_enc.c | 82 |
1 files changed, 32 insertions, 50 deletions
diff --git a/src/lib/libssl/t1_enc.c b/src/lib/libssl/t1_enc.c index e9a9713134..96b3aa6ca8 100644 --- a/src/lib/libssl/t1_enc.c +++ b/src/lib/libssl/t1_enc.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: t1_enc.c,v 1.102 2017/03/10 16:03:27 jsing Exp $ */ | 1 | /* $OpenBSD: t1_enc.c,v 1.103 2017/03/18 12:58:18 jsing Exp $ */ |
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
@@ -147,7 +147,7 @@ | |||
147 | int tls1_PRF(SSL *s, const void *seed1, int seed1_len, const void *seed2, | 147 | int tls1_PRF(SSL *s, const void *seed1, int seed1_len, const void *seed2, |
148 | int seed2_len, const void *seed3, int seed3_len, const void *seed4, | 148 | int seed2_len, const void *seed3, int seed3_len, const void *seed4, |
149 | int seed4_len, const void *seed5, int seed5_len, const unsigned char *sec, | 149 | int seed4_len, const void *seed5, int seed5_len, const unsigned char *sec, |
150 | int slen, unsigned char *out1, unsigned char *out2, int olen); | 150 | int slen, unsigned char *out, int olen); |
151 | 151 | ||
152 | void | 152 | void |
153 | tls1_cleanup_key_block(SSL *s) | 153 | tls1_cleanup_key_block(SSL *s) |
@@ -236,13 +236,13 @@ tls1_P_hash(const EVP_MD *md, const unsigned char *sec, int sec_len, | |||
236 | const void *seed3, int seed3_len, const void *seed4, int seed4_len, | 236 | const void *seed3, int seed3_len, const void *seed4, int seed4_len, |
237 | const void *seed5, int seed5_len, unsigned char *out, int olen) | 237 | const void *seed5, int seed5_len, unsigned char *out, int olen) |
238 | { | 238 | { |
239 | unsigned char A1[EVP_MAX_MD_SIZE]; | 239 | unsigned char A1[EVP_MAX_MD_SIZE], hmac[EVP_MAX_MD_SIZE]; |
240 | size_t A1_len, hmac_len; | ||
240 | EVP_MD_CTX ctx; | 241 | EVP_MD_CTX ctx; |
241 | EVP_PKEY *mac_key; | 242 | EVP_PKEY *mac_key; |
242 | size_t A1_len; | ||
243 | int ret = 0; | 243 | int ret = 0; |
244 | int chunk; | 244 | int chunk; |
245 | size_t j; | 245 | size_t i; |
246 | 246 | ||
247 | chunk = EVP_MD_size(md); | 247 | chunk = EVP_MD_size(md); |
248 | OPENSSL_assert(chunk >= 0); | 248 | OPENSSL_assert(chunk >= 0); |
@@ -282,18 +282,20 @@ tls1_P_hash(const EVP_MD *md, const unsigned char *sec, int sec_len, | |||
282 | goto err; | 282 | goto err; |
283 | if (seed5 && !EVP_DigestSignUpdate(&ctx, seed5, seed5_len)) | 283 | if (seed5 && !EVP_DigestSignUpdate(&ctx, seed5, seed5_len)) |
284 | goto err; | 284 | goto err; |
285 | if (!EVP_DigestSignFinal(&ctx, hmac, &hmac_len)) | ||
286 | goto err; | ||
285 | 287 | ||
286 | if (olen > chunk) { | 288 | if (hmac_len > olen) |
287 | if (!EVP_DigestSignFinal(&ctx, out, &j)) | 289 | hmac_len = olen; |
288 | goto err; | 290 | |
289 | out += j; | 291 | for (i = 0; i < hmac_len; i++) |
290 | olen -= j; | 292 | out[i] ^= hmac[i]; |
291 | } else { | 293 | |
292 | if (!EVP_DigestSignFinal(&ctx, A1, &A1_len)) | 294 | out += hmac_len; |
293 | goto err; | 295 | olen -= hmac_len; |
294 | memcpy(out, A1, olen); | 296 | |
297 | if (olen == 0) | ||
295 | break; | 298 | break; |
296 | } | ||
297 | 299 | ||
298 | if (!EVP_DigestSignInit(&ctx, NULL, md, NULL, mac_key)) | 300 | if (!EVP_DigestSignInit(&ctx, NULL, md, NULL, mac_key)) |
299 | goto err; | 301 | goto err; |
@@ -309,6 +311,7 @@ tls1_P_hash(const EVP_MD *md, const unsigned char *sec, int sec_len, | |||
309 | EVP_MD_CTX_cleanup(&ctx); | 311 | EVP_MD_CTX_cleanup(&ctx); |
310 | 312 | ||
311 | explicit_bzero(A1, sizeof(A1)); | 313 | explicit_bzero(A1, sizeof(A1)); |
314 | explicit_bzero(hmac, sizeof(hmac)); | ||
312 | 315 | ||
313 | return ret; | 316 | return ret; |
314 | } | 317 | } |
@@ -318,13 +321,12 @@ int | |||
318 | tls1_PRF(SSL *s, const void *seed1, int seed1_len, const void *seed2, | 321 | tls1_PRF(SSL *s, const void *seed1, int seed1_len, const void *seed2, |
319 | int seed2_len, const void *seed3, int seed3_len, const void *seed4, | 322 | int seed2_len, const void *seed3, int seed3_len, const void *seed4, |
320 | int seed4_len, const void *seed5, int seed5_len, const unsigned char *sec, | 323 | int seed4_len, const void *seed5, int seed5_len, const unsigned char *sec, |
321 | int slen, unsigned char *out1, unsigned char *out2, int olen) | 324 | int slen, unsigned char *out, int olen) |
322 | { | 325 | { |
323 | const EVP_MD *md; | 326 | const EVP_MD *md; |
324 | size_t hlen; | 327 | size_t hlen; |
325 | int i; | ||
326 | 328 | ||
327 | memset(out1, 0, olen); | 329 | memset(out, 0, olen); |
328 | 330 | ||
329 | if (!ssl_get_handshake_evp_md(s, &md)) | 331 | if (!ssl_get_handshake_evp_md(s, &md)) |
330 | return (0); | 332 | return (0); |
@@ -337,30 +339,27 @@ tls1_PRF(SSL *s, const void *seed1, int seed1_len, const void *seed2, | |||
337 | hlen = slen - (slen / 2); | 339 | hlen = slen - (slen / 2); |
338 | if (!tls1_P_hash(EVP_md5(), sec, hlen, seed1, seed1_len, seed2, | 340 | if (!tls1_P_hash(EVP_md5(), sec, hlen, seed1, seed1_len, seed2, |
339 | seed2_len, seed3, seed3_len, seed4, seed4_len, seed5, | 341 | seed2_len, seed3, seed3_len, seed4, seed4_len, seed5, |
340 | seed5_len, out1, olen)) | 342 | seed5_len, out, olen)) |
341 | return (0); | 343 | return (0); |
342 | 344 | ||
343 | sec += slen - hlen; | 345 | sec += slen - hlen; |
344 | if (!tls1_P_hash(EVP_sha1(), sec, hlen, seed1, seed1_len, seed2, | 346 | if (!tls1_P_hash(EVP_sha1(), sec, hlen, seed1, seed1_len, seed2, |
345 | seed2_len, seed3, seed3_len, seed4, seed4_len, seed5, | 347 | seed2_len, seed3, seed3_len, seed4, seed4_len, seed5, |
346 | seed5_len, out2, olen)) | 348 | seed5_len, out, olen)) |
347 | return (0); | 349 | return (0); |
348 | 350 | ||
349 | for (i = 0; i < olen; i++) | ||
350 | out1[i] ^= out2[i]; | ||
351 | |||
352 | return (1); | 351 | return (1); |
353 | } | 352 | } |
354 | 353 | ||
355 | if (!tls1_P_hash(md, sec, slen, seed1, seed1_len, seed2, seed2_len, | 354 | if (!tls1_P_hash(md, sec, slen, seed1, seed1_len, seed2, seed2_len, |
356 | seed3, seed3_len, seed4, seed4_len, seed5, seed5_len, out1, olen)) | 355 | seed3, seed3_len, seed4, seed4_len, seed5, seed5_len, out, olen)) |
357 | return (0); | 356 | return (0); |
358 | 357 | ||
359 | return (1); | 358 | return (1); |
360 | } | 359 | } |
361 | 360 | ||
362 | static int | 361 | static int |
363 | tls1_generate_key_block(SSL *s, unsigned char *km, unsigned char *tmp, int num) | 362 | tls1_generate_key_block(SSL *s, unsigned char *km, int num) |
364 | { | 363 | { |
365 | return tls1_PRF(s, | 364 | return tls1_PRF(s, |
366 | TLS_MD_KEY_EXPANSION_CONST, TLS_MD_KEY_EXPANSION_CONST_SIZE, | 365 | TLS_MD_KEY_EXPANSION_CONST, TLS_MD_KEY_EXPANSION_CONST_SIZE, |
@@ -368,7 +367,7 @@ tls1_generate_key_block(SSL *s, unsigned char *km, unsigned char *tmp, int num) | |||
368 | s->s3->client_random, SSL3_RANDOM_SIZE, | 367 | s->s3->client_random, SSL3_RANDOM_SIZE, |
369 | NULL, 0, NULL, 0, | 368 | NULL, 0, NULL, 0, |
370 | s->session->master_key, s->session->master_key_length, | 369 | s->session->master_key, s->session->master_key_length, |
371 | km, tmp, num); | 370 | km, num); |
372 | } | 371 | } |
373 | 372 | ||
374 | /* | 373 | /* |
@@ -658,7 +657,7 @@ err2: | |||
658 | int | 657 | int |
659 | tls1_setup_key_block(SSL *s) | 658 | tls1_setup_key_block(SSL *s) |
660 | { | 659 | { |
661 | unsigned char *key_block, *tmp_block = NULL; | 660 | unsigned char *key_block; |
662 | int mac_type = NID_undef, mac_secret_size = 0; | 661 | int mac_type = NID_undef, mac_secret_size = 0; |
663 | int key_block_len, key_len, iv_len; | 662 | int key_block_len, key_len, iv_len; |
664 | const EVP_CIPHER *cipher = NULL; | 663 | const EVP_CIPHER *cipher = NULL; |
@@ -709,12 +708,7 @@ tls1_setup_key_block(SSL *s) | |||
709 | S3I(s)->tmp.key_block_length = key_block_len; | 708 | S3I(s)->tmp.key_block_length = key_block_len; |
710 | S3I(s)->tmp.key_block = key_block; | 709 | S3I(s)->tmp.key_block = key_block; |
711 | 710 | ||
712 | if ((tmp_block = malloc(key_block_len)) == NULL) { | 711 | if (!tls1_generate_key_block(s, key_block, key_block_len)) |
713 | SSLerror(s, ERR_R_MALLOC_FAILURE); | ||
714 | goto err; | ||
715 | } | ||
716 | |||
717 | if (!tls1_generate_key_block(s, key_block, tmp_block, key_block_len)) | ||
718 | goto err; | 712 | goto err; |
719 | 713 | ||
720 | if (!(s->internal->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS) && | 714 | if (!(s->internal->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS) && |
@@ -738,11 +732,7 @@ tls1_setup_key_block(SSL *s) | |||
738 | 732 | ||
739 | ret = 1; | 733 | ret = 1; |
740 | 734 | ||
741 | err: | 735 | err: |
742 | if (tmp_block) { | ||
743 | explicit_bzero(tmp_block, key_block_len); | ||
744 | free(tmp_block); | ||
745 | } | ||
746 | return (ret); | 736 | return (ret); |
747 | } | 737 | } |
748 | 738 | ||
@@ -1044,7 +1034,7 @@ tls1_final_finish_mac(SSL *s, const char *str, int slen, unsigned char *out) | |||
1044 | 1034 | ||
1045 | if (!tls1_PRF(s, str, slen, buf1, hlen, NULL, 0, NULL, 0, NULL, 0, | 1035 | if (!tls1_PRF(s, str, slen, buf1, hlen, NULL, 0, NULL, 0, NULL, 0, |
1046 | s->session->master_key, s->session->master_key_length, | 1036 | s->session->master_key, s->session->master_key_length, |
1047 | out, buf2, sizeof(buf2))) | 1037 | out, 12)) |
1048 | return 0; | 1038 | return 0; |
1049 | 1039 | ||
1050 | return sizeof(buf2); | 1040 | return sizeof(buf2); |
@@ -1136,16 +1126,14 @@ int | |||
1136 | tls1_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p, | 1126 | tls1_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p, |
1137 | int len) | 1127 | int len) |
1138 | { | 1128 | { |
1139 | unsigned char buff[SSL_MAX_MASTER_KEY_LENGTH]; | ||
1140 | |||
1141 | /* XXX - check return value. */ | 1129 | /* XXX - check return value. */ |
1142 | tls1_PRF(s, | 1130 | tls1_PRF(s, |
1143 | TLS_MD_MASTER_SECRET_CONST, TLS_MD_MASTER_SECRET_CONST_SIZE, | 1131 | TLS_MD_MASTER_SECRET_CONST, TLS_MD_MASTER_SECRET_CONST_SIZE, |
1144 | s->s3->client_random, SSL3_RANDOM_SIZE, NULL, 0, | 1132 | s->s3->client_random, SSL3_RANDOM_SIZE, NULL, 0, |
1145 | s->s3->server_random, SSL3_RANDOM_SIZE, NULL, 0, | 1133 | s->s3->server_random, SSL3_RANDOM_SIZE, NULL, 0, |
1146 | p, len, s->session->master_key, buff, sizeof buff); | 1134 | p, len, s->session->master_key, SSL_MAX_MASTER_KEY_LENGTH); |
1147 | 1135 | ||
1148 | return (SSL3_MASTER_SECRET_SIZE); | 1136 | return (SSL_MAX_MASTER_KEY_LENGTH); |
1149 | } | 1137 | } |
1150 | 1138 | ||
1151 | int | 1139 | int |
@@ -1153,15 +1141,10 @@ tls1_export_keying_material(SSL *s, unsigned char *out, size_t olen, | |||
1153 | const char *label, size_t llen, const unsigned char *context, | 1141 | const char *label, size_t llen, const unsigned char *context, |
1154 | size_t contextlen, int use_context) | 1142 | size_t contextlen, int use_context) |
1155 | { | 1143 | { |
1156 | unsigned char *buff; | ||
1157 | unsigned char *val = NULL; | 1144 | unsigned char *val = NULL; |
1158 | size_t vallen, currentvalpos; | 1145 | size_t vallen, currentvalpos; |
1159 | int rv; | 1146 | int rv; |
1160 | 1147 | ||
1161 | buff = malloc(olen); | ||
1162 | if (buff == NULL) | ||
1163 | goto err2; | ||
1164 | |||
1165 | /* construct PRF arguments | 1148 | /* construct PRF arguments |
1166 | * we construct the PRF argument ourself rather than passing separate | 1149 | * we construct the PRF argument ourself rather than passing separate |
1167 | * values into the TLS PRF to ensure that the concatenation of values | 1150 | * values into the TLS PRF to ensure that the concatenation of values |
@@ -1213,7 +1196,7 @@ tls1_export_keying_material(SSL *s, unsigned char *out, size_t olen, | |||
1213 | 1196 | ||
1214 | rv = tls1_PRF(s, val, vallen, NULL, 0, NULL, 0, NULL, 0, NULL, 0, | 1197 | rv = tls1_PRF(s, val, vallen, NULL, 0, NULL, 0, NULL, 0, NULL, 0, |
1215 | s->session->master_key, s->session->master_key_length, | 1198 | s->session->master_key, s->session->master_key_length, |
1216 | out, buff, olen); | 1199 | out, olen); |
1217 | 1200 | ||
1218 | goto ret; | 1201 | goto ret; |
1219 | err1: | 1202 | err1: |
@@ -1224,7 +1207,6 @@ err2: | |||
1224 | SSLerror(s, ERR_R_MALLOC_FAILURE); | 1207 | SSLerror(s, ERR_R_MALLOC_FAILURE); |
1225 | rv = 0; | 1208 | rv = 0; |
1226 | ret: | 1209 | ret: |
1227 | free(buff); | ||
1228 | free(val); | 1210 | free(val); |
1229 | 1211 | ||
1230 | return (rv); | 1212 | return (rv); |