diff options
author | jsing <> | 2014-06-08 14:13:44 +0000 |
---|---|---|
committer | jsing <> | 2014-06-08 14:13:44 +0000 |
commit | 85519b20e273deb05b33f8d518d25eebbbcc5e16 (patch) | |
tree | f3e003eeabf2d1343274e52adc66363e511d7aea | |
parent | 6a02f02ad158f15d118cb88807d13ace8249ce97 (diff) | |
download | openbsd-85519b20e273deb05b33f8d518d25eebbbcc5e16.tar.gz openbsd-85519b20e273deb05b33f8d518d25eebbbcc5e16.tar.bz2 openbsd-85519b20e273deb05b33f8d518d25eebbbcc5e16.zip |
Factor out the part of tls1_change_cipher_state() that is specific to
switching cipher states using an EVP_CIPHER. This will facilitate the
addition of cipher state changes for EVP_AEAD. No functional change.
Based on Adam Langley's chromium patches.
-rw-r--r-- | src/lib/libssl/src/ssl/ssl.h | 1 | ||||
-rw-r--r-- | src/lib/libssl/src/ssl/ssl_err.c | 1 | ||||
-rw-r--r-- | src/lib/libssl/src/ssl/t1_enc.c | 279 | ||||
-rw-r--r-- | src/lib/libssl/ssl.h | 1 | ||||
-rw-r--r-- | src/lib/libssl/ssl_err.c | 1 | ||||
-rw-r--r-- | src/lib/libssl/t1_enc.c | 279 |
6 files changed, 310 insertions, 252 deletions
diff --git a/src/lib/libssl/src/ssl/ssl.h b/src/lib/libssl/src/ssl/ssl.h index 0c5d76bc23..8fc8c107b4 100644 --- a/src/lib/libssl/src/ssl/ssl.h +++ b/src/lib/libssl/src/ssl/ssl.h | |||
@@ -2084,6 +2084,7 @@ void ERR_load_SSL_strings(void); | |||
2084 | #define SSL_F_SSL_VERIFY_CERT_CHAIN 207 | 2084 | #define SSL_F_SSL_VERIFY_CERT_CHAIN 207 |
2085 | #define SSL_F_SSL_WRITE 208 | 2085 | #define SSL_F_SSL_WRITE 208 |
2086 | #define SSL_F_TLS1_CERT_VERIFY_MAC 286 | 2086 | #define SSL_F_TLS1_CERT_VERIFY_MAC 286 |
2087 | #define SSL_F_TLS1_CHANGE_CIPHER_STATE_CIPHER 338 | ||
2087 | #define SSL_F_TLS1_CHANGE_CIPHER_STATE 209 | 2088 | #define SSL_F_TLS1_CHANGE_CIPHER_STATE 209 |
2088 | #define SSL_F_TLS1_CHECK_SERVERHELLO_TLSEXT 274 | 2089 | #define SSL_F_TLS1_CHECK_SERVERHELLO_TLSEXT 274 |
2089 | #define SSL_F_TLS1_ENC 210 | 2090 | #define SSL_F_TLS1_ENC 210 |
diff --git a/src/lib/libssl/src/ssl/ssl_err.c b/src/lib/libssl/src/ssl/ssl_err.c index b21fe939a5..c53f2b6c90 100644 --- a/src/lib/libssl/src/ssl/ssl_err.c +++ b/src/lib/libssl/src/ssl/ssl_err.c | |||
@@ -137,6 +137,7 @@ static ERR_STRING_DATA SSL_str_functs[]= { | |||
137 | {ERR_FUNC(SSL_F_SSL3_ADD_CERT_TO_BUF), "SSL3_ADD_CERT_TO_BUF"}, | 137 | {ERR_FUNC(SSL_F_SSL3_ADD_CERT_TO_BUF), "SSL3_ADD_CERT_TO_BUF"}, |
138 | {ERR_FUNC(SSL_F_SSL3_CALLBACK_CTRL), "SSL3_CALLBACK_CTRL"}, | 138 | {ERR_FUNC(SSL_F_SSL3_CALLBACK_CTRL), "SSL3_CALLBACK_CTRL"}, |
139 | {ERR_FUNC(SSL_F_SSL3_CHANGE_CIPHER_STATE), "SSL3_CHANGE_CIPHER_STATE"}, | 139 | {ERR_FUNC(SSL_F_SSL3_CHANGE_CIPHER_STATE), "SSL3_CHANGE_CIPHER_STATE"}, |
140 | {ERR_FUNC(SSL_F_TLS1_CHANGE_CIPHER_STATE_CIPHER), "TLS1_CHANGE_CIPHER_STATE_CIPHER"}, | ||
140 | {ERR_FUNC(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM), "SSL3_CHECK_CERT_AND_ALGORITHM"}, | 141 | {ERR_FUNC(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM), "SSL3_CHECK_CERT_AND_ALGORITHM"}, |
141 | {ERR_FUNC(SSL_F_SSL3_CHECK_CLIENT_HELLO), "SSL3_CHECK_CLIENT_HELLO"}, | 142 | {ERR_FUNC(SSL_F_SSL3_CHECK_CLIENT_HELLO), "SSL3_CHECK_CLIENT_HELLO"}, |
142 | {ERR_FUNC(SSL_F_SSL3_CLIENT_HELLO), "SSL3_CLIENT_HELLO"}, | 143 | {ERR_FUNC(SSL_F_SSL3_CLIENT_HELLO), "SSL3_CLIENT_HELLO"}, |
diff --git a/src/lib/libssl/src/ssl/t1_enc.c b/src/lib/libssl/src/ssl/t1_enc.c index 55f4d72073..5f5c8e3488 100644 --- a/src/lib/libssl/src/ssl/t1_enc.c +++ b/src/lib/libssl/src/ssl/t1_enc.c | |||
@@ -297,38 +297,176 @@ tls1_generate_key_block(SSL *s, unsigned char *km, unsigned char *tmp, int num) | |||
297 | return ret; | 297 | return ret; |
298 | } | 298 | } |
299 | 299 | ||
300 | int | 300 | /* |
301 | tls1_change_cipher_state(SSL *s, int which) | 301 | * tls1_change_cipher_state_cipher performs the work needed to switch cipher |
302 | * states when using EVP_CIPHER. The argument is_read is true iff this function | ||
303 | * is being called due to reading, as opposed to writing, a ChangeCipherSpec | ||
304 | * message. In order to support export ciphersuites, use_client_keys indicates | ||
305 | * whether the key material provided is in the "client write" direction. | ||
306 | */ | ||
307 | static int | ||
308 | tls1_change_cipher_state_cipher(SSL *s, char is_read, char use_client_keys, | ||
309 | const unsigned char *mac_secret, unsigned mac_secret_size, | ||
310 | const unsigned char *key, unsigned key_len, const unsigned char *iv, | ||
311 | unsigned iv_len) | ||
302 | { | 312 | { |
303 | static const unsigned char empty[] = ""; | 313 | static const unsigned char empty[] = ""; |
304 | unsigned char export_tmp1[EVP_MAX_KEY_LENGTH]; | 314 | unsigned char export_tmp1[EVP_MAX_KEY_LENGTH]; |
305 | unsigned char export_tmp2[EVP_MAX_KEY_LENGTH]; | 315 | unsigned char export_tmp2[EVP_MAX_KEY_LENGTH]; |
306 | unsigned char export_iv1[EVP_MAX_IV_LENGTH * 2]; | 316 | unsigned char export_iv1[EVP_MAX_IV_LENGTH * 2]; |
307 | unsigned char export_iv2[EVP_MAX_IV_LENGTH * 2]; | 317 | unsigned char export_iv2[EVP_MAX_IV_LENGTH * 2]; |
318 | unsigned char *exp_label; | ||
319 | int exp_label_len; | ||
320 | EVP_CIPHER_CTX *cipher_ctx; | ||
321 | const EVP_CIPHER *cipher; | ||
322 | EVP_MD_CTX *mac_ctx; | ||
323 | const EVP_MD *mac; | ||
324 | EVP_PKEY *mac_key; | ||
325 | int mac_type; | ||
326 | int is_export; | ||
327 | |||
328 | is_export = SSL_C_IS_EXPORT(s->s3->tmp.new_cipher); | ||
329 | cipher = s->s3->tmp.new_sym_enc; | ||
330 | mac = s->s3->tmp.new_hash; | ||
331 | mac_type = s->s3->tmp.new_mac_pkey_type; | ||
332 | |||
333 | if (is_read) { | ||
334 | if (s->s3->tmp.new_cipher->algorithm2 & TLS1_STREAM_MAC) | ||
335 | s->mac_flags |= SSL_MAC_FLAG_READ_MAC_STREAM; | ||
336 | else | ||
337 | s->mac_flags &= ~SSL_MAC_FLAG_READ_MAC_STREAM; | ||
338 | |||
339 | EVP_CIPHER_CTX_free(s->enc_read_ctx); | ||
340 | s->enc_read_ctx = NULL; | ||
341 | EVP_MD_CTX_destroy(s->read_hash); | ||
342 | s->read_hash = NULL; | ||
343 | |||
344 | if ((cipher_ctx = EVP_CIPHER_CTX_new()) == NULL) | ||
345 | goto err; | ||
346 | s->enc_read_ctx = cipher_ctx; | ||
347 | if ((mac_ctx = EVP_MD_CTX_create()) == NULL) | ||
348 | goto err; | ||
349 | s->read_hash = mac_ctx; | ||
350 | } else { | ||
351 | if (s->s3->tmp.new_cipher->algorithm2 & TLS1_STREAM_MAC) | ||
352 | s->mac_flags |= SSL_MAC_FLAG_WRITE_MAC_STREAM; | ||
353 | else | ||
354 | s->mac_flags &= ~SSL_MAC_FLAG_WRITE_MAC_STREAM; | ||
355 | |||
356 | /* | ||
357 | * DTLS fragments retain a pointer to the compression, cipher | ||
358 | * and hash contexts, so that it can restore state in order | ||
359 | * to perform retransmissions. As such, we cannot free write | ||
360 | * contexts that are used for DTLS - these are instead freed | ||
361 | * by DTLS when its frees a ChangeCipherSpec fragment. | ||
362 | */ | ||
363 | if (!SSL_IS_DTLS(s)) { | ||
364 | EVP_CIPHER_CTX_free(s->enc_write_ctx); | ||
365 | s->enc_write_ctx = NULL; | ||
366 | EVP_MD_CTX_destroy(s->write_hash); | ||
367 | s->write_hash = NULL; | ||
368 | } | ||
369 | if ((cipher_ctx = EVP_CIPHER_CTX_new()) == NULL) | ||
370 | goto err; | ||
371 | s->enc_write_ctx = cipher_ctx; | ||
372 | if ((mac_ctx = EVP_MD_CTX_create()) == NULL) | ||
373 | goto err; | ||
374 | s->write_hash = mac_ctx; | ||
375 | } | ||
376 | |||
377 | if (!(EVP_CIPHER_flags(cipher) & EVP_CIPH_FLAG_AEAD_CIPHER)) { | ||
378 | mac_key = EVP_PKEY_new_mac_key(mac_type, NULL, | ||
379 | mac_secret, mac_secret_size); | ||
380 | if (mac_key == NULL) | ||
381 | goto err; | ||
382 | EVP_DigestSignInit(mac_ctx, NULL, mac, NULL, mac_key); | ||
383 | EVP_PKEY_free(mac_key); | ||
384 | } | ||
308 | 385 | ||
386 | if (is_export) { | ||
387 | /* | ||
388 | * Both the read and write key/iv are set to the same value | ||
389 | * since only the correct one will be used :-). | ||
390 | */ | ||
391 | if (use_client_keys) { | ||
392 | exp_label = TLS_MD_CLIENT_WRITE_KEY_CONST; | ||
393 | exp_label_len = TLS_MD_CLIENT_WRITE_KEY_CONST_SIZE; | ||
394 | } else { | ||
395 | exp_label = TLS_MD_SERVER_WRITE_KEY_CONST; | ||
396 | exp_label_len = TLS_MD_SERVER_WRITE_KEY_CONST_SIZE; | ||
397 | } | ||
398 | if (!tls1_PRF(ssl_get_algorithm2(s), | ||
399 | exp_label, exp_label_len, | ||
400 | s->s3->client_random, SSL3_RANDOM_SIZE, | ||
401 | s->s3->server_random, SSL3_RANDOM_SIZE, | ||
402 | NULL, 0, NULL, 0, key, key_len, export_tmp1, export_tmp2, | ||
403 | EVP_CIPHER_key_length(cipher))) | ||
404 | goto err2; | ||
405 | key = export_tmp1; | ||
406 | |||
407 | if (iv_len > 0) { | ||
408 | if (!tls1_PRF(ssl_get_algorithm2(s), | ||
409 | TLS_MD_IV_BLOCK_CONST, TLS_MD_IV_BLOCK_CONST_SIZE, | ||
410 | s->s3->client_random, SSL3_RANDOM_SIZE, | ||
411 | s->s3->server_random, SSL3_RANDOM_SIZE, | ||
412 | NULL, 0, NULL, 0, empty, 0, | ||
413 | export_iv1, export_iv2, iv_len * 2)) | ||
414 | goto err2; | ||
415 | if (use_client_keys) | ||
416 | iv = export_iv1; | ||
417 | else | ||
418 | iv = &(export_iv1[iv_len]); | ||
419 | } | ||
420 | } | ||
421 | |||
422 | if (EVP_CIPHER_mode(cipher) == EVP_CIPH_GCM_MODE) { | ||
423 | EVP_CipherInit_ex(cipher_ctx, cipher, NULL, key, NULL, | ||
424 | !is_read); | ||
425 | EVP_CIPHER_CTX_ctrl(cipher_ctx, EVP_CTRL_GCM_SET_IV_FIXED, | ||
426 | iv_len, (unsigned char *)iv); | ||
427 | } else | ||
428 | EVP_CipherInit_ex(cipher_ctx, cipher, NULL, key, iv, !is_read); | ||
429 | |||
430 | /* Needed for "composite" AEADs, such as RC4-HMAC-MD5 */ | ||
431 | if ((EVP_CIPHER_flags(cipher) & EVP_CIPH_FLAG_AEAD_CIPHER) && | ||
432 | mac_secret_size) | ||
433 | EVP_CIPHER_CTX_ctrl(cipher_ctx, EVP_CTRL_AEAD_SET_MAC_KEY, | ||
434 | mac_secret_size, (unsigned char *)mac_secret); | ||
435 | |||
436 | if (is_export) { | ||
437 | OPENSSL_cleanse(export_tmp1, sizeof(export_tmp1)); | ||
438 | OPENSSL_cleanse(export_tmp2, sizeof(export_tmp2)); | ||
439 | OPENSSL_cleanse(export_iv1, sizeof(export_iv1)); | ||
440 | OPENSSL_cleanse(export_iv2, sizeof(export_iv2)); | ||
441 | } | ||
442 | |||
443 | return (1); | ||
444 | |||
445 | err: | ||
446 | SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE_CIPHER, ERR_R_MALLOC_FAILURE); | ||
447 | err2: | ||
448 | return (0); | ||
449 | } | ||
450 | |||
451 | int | ||
452 | tls1_change_cipher_state(SSL *s, int which) | ||
453 | { | ||
309 | const unsigned char *client_write_mac_secret, *server_write_mac_secret; | 454 | const unsigned char *client_write_mac_secret, *server_write_mac_secret; |
310 | const unsigned char *client_write_key, *server_write_key; | 455 | const unsigned char *client_write_key, *server_write_key; |
311 | const unsigned char *client_write_iv, *server_write_iv; | 456 | const unsigned char *client_write_iv, *server_write_iv; |
312 | const unsigned char *mac_secret, *key, *iv; | 457 | const unsigned char *mac_secret, *key, *iv; |
313 | int mac_secret_size, key_len, iv_len; | 458 | int mac_secret_size, key_len, iv_len; |
314 | unsigned char *key_block, *exp_label, *seq; | 459 | unsigned char *key_block, *seq; |
315 | |||
316 | EVP_CIPHER_CTX *cipher_ctx; | ||
317 | const EVP_CIPHER *cipher; | 460 | const EVP_CIPHER *cipher; |
461 | char is_read, use_client_keys; | ||
462 | int is_export; | ||
463 | |||
318 | #ifndef OPENSSL_NO_COMP | 464 | #ifndef OPENSSL_NO_COMP |
319 | const SSL_COMP *comp; | 465 | const SSL_COMP *comp; |
320 | #endif | 466 | #endif |
321 | const EVP_MD *mac; | ||
322 | int mac_type; | ||
323 | EVP_MD_CTX *mac_ctx; | ||
324 | EVP_PKEY *mac_key; | ||
325 | int is_export, exp_label_len; | ||
326 | char is_read, use_client_keys; | ||
327 | 467 | ||
328 | is_export = SSL_C_IS_EXPORT(s->s3->tmp.new_cipher); | 468 | is_export = SSL_C_IS_EXPORT(s->s3->tmp.new_cipher); |
329 | cipher = s->s3->tmp.new_sym_enc; | 469 | cipher = s->s3->tmp.new_sym_enc; |
330 | mac = s->s3->tmp.new_hash; | ||
331 | mac_type = s->s3->tmp.new_mac_pkey_type; | ||
332 | 470 | ||
333 | /* | 471 | /* |
334 | * is_read is true if we have just read a ChangeCipherSpec message, | 472 | * is_read is true if we have just read a ChangeCipherSpec message, |
@@ -381,51 +519,6 @@ tls1_change_cipher_state(SSL *s, int which) | |||
381 | } | 519 | } |
382 | #endif | 520 | #endif |
383 | 521 | ||
384 | if (is_read) { | ||
385 | if (s->s3->tmp.new_cipher->algorithm2 & TLS1_STREAM_MAC) | ||
386 | s->mac_flags |= SSL_MAC_FLAG_READ_MAC_STREAM; | ||
387 | else | ||
388 | s->mac_flags &= ~SSL_MAC_FLAG_READ_MAC_STREAM; | ||
389 | |||
390 | EVP_CIPHER_CTX_free(s->enc_read_ctx); | ||
391 | s->enc_read_ctx = NULL; | ||
392 | EVP_MD_CTX_destroy(s->read_hash); | ||
393 | s->read_hash = NULL; | ||
394 | |||
395 | if ((cipher_ctx = EVP_CIPHER_CTX_new()) == NULL) | ||
396 | goto err; | ||
397 | s->enc_read_ctx = cipher_ctx; | ||
398 | if ((mac_ctx = EVP_MD_CTX_create()) == NULL) | ||
399 | goto err; | ||
400 | s->read_hash = mac_ctx; | ||
401 | } else { | ||
402 | if (s->s3->tmp.new_cipher->algorithm2 & TLS1_STREAM_MAC) | ||
403 | s->mac_flags |= SSL_MAC_FLAG_WRITE_MAC_STREAM; | ||
404 | else | ||
405 | s->mac_flags &= ~SSL_MAC_FLAG_WRITE_MAC_STREAM; | ||
406 | |||
407 | /* | ||
408 | * DTLS fragments retain a pointer to the compression, cipher | ||
409 | * and hash contexts, so that it can restore state in order | ||
410 | * to perform retransmissions. As such, we cannot free write | ||
411 | * contexts that are used for DTLS - these are instead freed | ||
412 | * by DTLS when its frees a ChangeCipherSpec fragment. | ||
413 | */ | ||
414 | if (!SSL_IS_DTLS(s)) { | ||
415 | EVP_CIPHER_CTX_free(s->enc_write_ctx); | ||
416 | s->enc_write_ctx = NULL; | ||
417 | EVP_MD_CTX_destroy(s->write_hash); | ||
418 | s->write_hash = NULL; | ||
419 | } | ||
420 | if ((cipher_ctx = EVP_CIPHER_CTX_new()) == NULL) | ||
421 | goto err; | ||
422 | s->enc_write_ctx = cipher_ctx; | ||
423 | if ((mac_ctx = EVP_MD_CTX_create()) == NULL) | ||
424 | goto err; | ||
425 | s->write_hash = mac_ctx; | ||
426 | |||
427 | } | ||
428 | |||
429 | /* | 522 | /* |
430 | * Reset sequence number to zero - for DTLS this is handled in | 523 | * Reset sequence number to zero - for DTLS this is handled in |
431 | * dtls1_reset_seq_numbers(). | 524 | * dtls1_reset_seq_numbers(). |
@@ -486,74 +579,8 @@ tls1_change_cipher_state(SSL *s, int which) | |||
486 | s->s3->write_mac_secret_size = mac_secret_size; | 579 | s->s3->write_mac_secret_size = mac_secret_size; |
487 | } | 580 | } |
488 | 581 | ||
489 | if (!(EVP_CIPHER_flags(cipher) & EVP_CIPH_FLAG_AEAD_CIPHER)) { | 582 | return tls1_change_cipher_state_cipher(s, is_read, use_client_keys, |
490 | mac_key = EVP_PKEY_new_mac_key(mac_type, NULL, | 583 | mac_secret, mac_secret_size, key, key_len, iv, iv_len); |
491 | mac_secret, mac_secret_size); | ||
492 | if (mac_key == NULL) | ||
493 | goto err; | ||
494 | EVP_DigestSignInit(mac_ctx, NULL, mac, NULL, mac_key); | ||
495 | EVP_PKEY_free(mac_key); | ||
496 | } | ||
497 | |||
498 | if (is_export) { | ||
499 | /* | ||
500 | * Both the read and write key/iv are set to the same value | ||
501 | * since only the correct one will be used :-). | ||
502 | */ | ||
503 | if (use_client_keys) { | ||
504 | exp_label = TLS_MD_CLIENT_WRITE_KEY_CONST; | ||
505 | exp_label_len = TLS_MD_CLIENT_WRITE_KEY_CONST_SIZE; | ||
506 | } else { | ||
507 | exp_label = TLS_MD_SERVER_WRITE_KEY_CONST; | ||
508 | exp_label_len = TLS_MD_SERVER_WRITE_KEY_CONST_SIZE; | ||
509 | } | ||
510 | |||
511 | if (!tls1_PRF(ssl_get_algorithm2(s), | ||
512 | exp_label, exp_label_len, | ||
513 | s->s3->client_random, SSL3_RANDOM_SIZE, | ||
514 | s->s3->server_random, SSL3_RANDOM_SIZE, | ||
515 | NULL, 0, NULL, 0, key, key_len, export_tmp1, export_tmp2, | ||
516 | EVP_CIPHER_key_length(cipher))) | ||
517 | goto err2; | ||
518 | key = export_tmp1; | ||
519 | |||
520 | if (iv_len > 0) { | ||
521 | if (!tls1_PRF(ssl_get_algorithm2(s), | ||
522 | TLS_MD_IV_BLOCK_CONST, TLS_MD_IV_BLOCK_CONST_SIZE, | ||
523 | s->s3->client_random, SSL3_RANDOM_SIZE, | ||
524 | s->s3->server_random, SSL3_RANDOM_SIZE, | ||
525 | NULL, 0, NULL, 0, empty, 0, | ||
526 | export_iv1, export_iv2, iv_len * 2)) | ||
527 | goto err2; | ||
528 | if (use_client_keys) | ||
529 | iv = export_iv1; | ||
530 | else | ||
531 | iv = &(export_iv1[iv_len]); | ||
532 | } | ||
533 | } | ||
534 | |||
535 | if (EVP_CIPHER_mode(cipher) == EVP_CIPH_GCM_MODE) { | ||
536 | EVP_CipherInit_ex(cipher_ctx, cipher, NULL, key, NULL, | ||
537 | !is_read); | ||
538 | EVP_CIPHER_CTX_ctrl(cipher_ctx, EVP_CTRL_GCM_SET_IV_FIXED, | ||
539 | iv_len, (unsigned char *)iv); | ||
540 | } else | ||
541 | EVP_CipherInit_ex(cipher_ctx, cipher, NULL, key, iv, !is_read); | ||
542 | |||
543 | /* Needed for "composite" AEADs, such as RC4-HMAC-MD5 */ | ||
544 | if ((EVP_CIPHER_flags(cipher) & EVP_CIPH_FLAG_AEAD_CIPHER) && | ||
545 | mac_secret_size) | ||
546 | EVP_CIPHER_CTX_ctrl(cipher_ctx, EVP_CTRL_AEAD_SET_MAC_KEY, | ||
547 | mac_secret_size, (unsigned char *)mac_secret); | ||
548 | |||
549 | if (is_export) { | ||
550 | OPENSSL_cleanse(export_tmp1, sizeof(export_tmp1)); | ||
551 | OPENSSL_cleanse(export_tmp2, sizeof(export_tmp2)); | ||
552 | OPENSSL_cleanse(export_iv1, sizeof(export_iv1)); | ||
553 | OPENSSL_cleanse(export_iv2, sizeof(export_iv2)); | ||
554 | } | ||
555 | |||
556 | return (1); | ||
557 | 584 | ||
558 | err: | 585 | err: |
559 | SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE, ERR_R_MALLOC_FAILURE); | 586 | SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE, ERR_R_MALLOC_FAILURE); |
diff --git a/src/lib/libssl/ssl.h b/src/lib/libssl/ssl.h index 0c5d76bc23..8fc8c107b4 100644 --- a/src/lib/libssl/ssl.h +++ b/src/lib/libssl/ssl.h | |||
@@ -2084,6 +2084,7 @@ void ERR_load_SSL_strings(void); | |||
2084 | #define SSL_F_SSL_VERIFY_CERT_CHAIN 207 | 2084 | #define SSL_F_SSL_VERIFY_CERT_CHAIN 207 |
2085 | #define SSL_F_SSL_WRITE 208 | 2085 | #define SSL_F_SSL_WRITE 208 |
2086 | #define SSL_F_TLS1_CERT_VERIFY_MAC 286 | 2086 | #define SSL_F_TLS1_CERT_VERIFY_MAC 286 |
2087 | #define SSL_F_TLS1_CHANGE_CIPHER_STATE_CIPHER 338 | ||
2087 | #define SSL_F_TLS1_CHANGE_CIPHER_STATE 209 | 2088 | #define SSL_F_TLS1_CHANGE_CIPHER_STATE 209 |
2088 | #define SSL_F_TLS1_CHECK_SERVERHELLO_TLSEXT 274 | 2089 | #define SSL_F_TLS1_CHECK_SERVERHELLO_TLSEXT 274 |
2089 | #define SSL_F_TLS1_ENC 210 | 2090 | #define SSL_F_TLS1_ENC 210 |
diff --git a/src/lib/libssl/ssl_err.c b/src/lib/libssl/ssl_err.c index b21fe939a5..c53f2b6c90 100644 --- a/src/lib/libssl/ssl_err.c +++ b/src/lib/libssl/ssl_err.c | |||
@@ -137,6 +137,7 @@ static ERR_STRING_DATA SSL_str_functs[]= { | |||
137 | {ERR_FUNC(SSL_F_SSL3_ADD_CERT_TO_BUF), "SSL3_ADD_CERT_TO_BUF"}, | 137 | {ERR_FUNC(SSL_F_SSL3_ADD_CERT_TO_BUF), "SSL3_ADD_CERT_TO_BUF"}, |
138 | {ERR_FUNC(SSL_F_SSL3_CALLBACK_CTRL), "SSL3_CALLBACK_CTRL"}, | 138 | {ERR_FUNC(SSL_F_SSL3_CALLBACK_CTRL), "SSL3_CALLBACK_CTRL"}, |
139 | {ERR_FUNC(SSL_F_SSL3_CHANGE_CIPHER_STATE), "SSL3_CHANGE_CIPHER_STATE"}, | 139 | {ERR_FUNC(SSL_F_SSL3_CHANGE_CIPHER_STATE), "SSL3_CHANGE_CIPHER_STATE"}, |
140 | {ERR_FUNC(SSL_F_TLS1_CHANGE_CIPHER_STATE_CIPHER), "TLS1_CHANGE_CIPHER_STATE_CIPHER"}, | ||
140 | {ERR_FUNC(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM), "SSL3_CHECK_CERT_AND_ALGORITHM"}, | 141 | {ERR_FUNC(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM), "SSL3_CHECK_CERT_AND_ALGORITHM"}, |
141 | {ERR_FUNC(SSL_F_SSL3_CHECK_CLIENT_HELLO), "SSL3_CHECK_CLIENT_HELLO"}, | 142 | {ERR_FUNC(SSL_F_SSL3_CHECK_CLIENT_HELLO), "SSL3_CHECK_CLIENT_HELLO"}, |
142 | {ERR_FUNC(SSL_F_SSL3_CLIENT_HELLO), "SSL3_CLIENT_HELLO"}, | 143 | {ERR_FUNC(SSL_F_SSL3_CLIENT_HELLO), "SSL3_CLIENT_HELLO"}, |
diff --git a/src/lib/libssl/t1_enc.c b/src/lib/libssl/t1_enc.c index 55f4d72073..5f5c8e3488 100644 --- a/src/lib/libssl/t1_enc.c +++ b/src/lib/libssl/t1_enc.c | |||
@@ -297,38 +297,176 @@ tls1_generate_key_block(SSL *s, unsigned char *km, unsigned char *tmp, int num) | |||
297 | return ret; | 297 | return ret; |
298 | } | 298 | } |
299 | 299 | ||
300 | int | 300 | /* |
301 | tls1_change_cipher_state(SSL *s, int which) | 301 | * tls1_change_cipher_state_cipher performs the work needed to switch cipher |
302 | * states when using EVP_CIPHER. The argument is_read is true iff this function | ||
303 | * is being called due to reading, as opposed to writing, a ChangeCipherSpec | ||
304 | * message. In order to support export ciphersuites, use_client_keys indicates | ||
305 | * whether the key material provided is in the "client write" direction. | ||
306 | */ | ||
307 | static int | ||
308 | tls1_change_cipher_state_cipher(SSL *s, char is_read, char use_client_keys, | ||
309 | const unsigned char *mac_secret, unsigned mac_secret_size, | ||
310 | const unsigned char *key, unsigned key_len, const unsigned char *iv, | ||
311 | unsigned iv_len) | ||
302 | { | 312 | { |
303 | static const unsigned char empty[] = ""; | 313 | static const unsigned char empty[] = ""; |
304 | unsigned char export_tmp1[EVP_MAX_KEY_LENGTH]; | 314 | unsigned char export_tmp1[EVP_MAX_KEY_LENGTH]; |
305 | unsigned char export_tmp2[EVP_MAX_KEY_LENGTH]; | 315 | unsigned char export_tmp2[EVP_MAX_KEY_LENGTH]; |
306 | unsigned char export_iv1[EVP_MAX_IV_LENGTH * 2]; | 316 | unsigned char export_iv1[EVP_MAX_IV_LENGTH * 2]; |
307 | unsigned char export_iv2[EVP_MAX_IV_LENGTH * 2]; | 317 | unsigned char export_iv2[EVP_MAX_IV_LENGTH * 2]; |
318 | unsigned char *exp_label; | ||
319 | int exp_label_len; | ||
320 | EVP_CIPHER_CTX *cipher_ctx; | ||
321 | const EVP_CIPHER *cipher; | ||
322 | EVP_MD_CTX *mac_ctx; | ||
323 | const EVP_MD *mac; | ||
324 | EVP_PKEY *mac_key; | ||
325 | int mac_type; | ||
326 | int is_export; | ||
327 | |||
328 | is_export = SSL_C_IS_EXPORT(s->s3->tmp.new_cipher); | ||
329 | cipher = s->s3->tmp.new_sym_enc; | ||
330 | mac = s->s3->tmp.new_hash; | ||
331 | mac_type = s->s3->tmp.new_mac_pkey_type; | ||
332 | |||
333 | if (is_read) { | ||
334 | if (s->s3->tmp.new_cipher->algorithm2 & TLS1_STREAM_MAC) | ||
335 | s->mac_flags |= SSL_MAC_FLAG_READ_MAC_STREAM; | ||
336 | else | ||
337 | s->mac_flags &= ~SSL_MAC_FLAG_READ_MAC_STREAM; | ||
338 | |||
339 | EVP_CIPHER_CTX_free(s->enc_read_ctx); | ||
340 | s->enc_read_ctx = NULL; | ||
341 | EVP_MD_CTX_destroy(s->read_hash); | ||
342 | s->read_hash = NULL; | ||
343 | |||
344 | if ((cipher_ctx = EVP_CIPHER_CTX_new()) == NULL) | ||
345 | goto err; | ||
346 | s->enc_read_ctx = cipher_ctx; | ||
347 | if ((mac_ctx = EVP_MD_CTX_create()) == NULL) | ||
348 | goto err; | ||
349 | s->read_hash = mac_ctx; | ||
350 | } else { | ||
351 | if (s->s3->tmp.new_cipher->algorithm2 & TLS1_STREAM_MAC) | ||
352 | s->mac_flags |= SSL_MAC_FLAG_WRITE_MAC_STREAM; | ||
353 | else | ||
354 | s->mac_flags &= ~SSL_MAC_FLAG_WRITE_MAC_STREAM; | ||
355 | |||
356 | /* | ||
357 | * DTLS fragments retain a pointer to the compression, cipher | ||
358 | * and hash contexts, so that it can restore state in order | ||
359 | * to perform retransmissions. As such, we cannot free write | ||
360 | * contexts that are used for DTLS - these are instead freed | ||
361 | * by DTLS when its frees a ChangeCipherSpec fragment. | ||
362 | */ | ||
363 | if (!SSL_IS_DTLS(s)) { | ||
364 | EVP_CIPHER_CTX_free(s->enc_write_ctx); | ||
365 | s->enc_write_ctx = NULL; | ||
366 | EVP_MD_CTX_destroy(s->write_hash); | ||
367 | s->write_hash = NULL; | ||
368 | } | ||
369 | if ((cipher_ctx = EVP_CIPHER_CTX_new()) == NULL) | ||
370 | goto err; | ||
371 | s->enc_write_ctx = cipher_ctx; | ||
372 | if ((mac_ctx = EVP_MD_CTX_create()) == NULL) | ||
373 | goto err; | ||
374 | s->write_hash = mac_ctx; | ||
375 | } | ||
376 | |||
377 | if (!(EVP_CIPHER_flags(cipher) & EVP_CIPH_FLAG_AEAD_CIPHER)) { | ||
378 | mac_key = EVP_PKEY_new_mac_key(mac_type, NULL, | ||
379 | mac_secret, mac_secret_size); | ||
380 | if (mac_key == NULL) | ||
381 | goto err; | ||
382 | EVP_DigestSignInit(mac_ctx, NULL, mac, NULL, mac_key); | ||
383 | EVP_PKEY_free(mac_key); | ||
384 | } | ||
308 | 385 | ||
386 | if (is_export) { | ||
387 | /* | ||
388 | * Both the read and write key/iv are set to the same value | ||
389 | * since only the correct one will be used :-). | ||
390 | */ | ||
391 | if (use_client_keys) { | ||
392 | exp_label = TLS_MD_CLIENT_WRITE_KEY_CONST; | ||
393 | exp_label_len = TLS_MD_CLIENT_WRITE_KEY_CONST_SIZE; | ||
394 | } else { | ||
395 | exp_label = TLS_MD_SERVER_WRITE_KEY_CONST; | ||
396 | exp_label_len = TLS_MD_SERVER_WRITE_KEY_CONST_SIZE; | ||
397 | } | ||
398 | if (!tls1_PRF(ssl_get_algorithm2(s), | ||
399 | exp_label, exp_label_len, | ||
400 | s->s3->client_random, SSL3_RANDOM_SIZE, | ||
401 | s->s3->server_random, SSL3_RANDOM_SIZE, | ||
402 | NULL, 0, NULL, 0, key, key_len, export_tmp1, export_tmp2, | ||
403 | EVP_CIPHER_key_length(cipher))) | ||
404 | goto err2; | ||
405 | key = export_tmp1; | ||
406 | |||
407 | if (iv_len > 0) { | ||
408 | if (!tls1_PRF(ssl_get_algorithm2(s), | ||
409 | TLS_MD_IV_BLOCK_CONST, TLS_MD_IV_BLOCK_CONST_SIZE, | ||
410 | s->s3->client_random, SSL3_RANDOM_SIZE, | ||
411 | s->s3->server_random, SSL3_RANDOM_SIZE, | ||
412 | NULL, 0, NULL, 0, empty, 0, | ||
413 | export_iv1, export_iv2, iv_len * 2)) | ||
414 | goto err2; | ||
415 | if (use_client_keys) | ||
416 | iv = export_iv1; | ||
417 | else | ||
418 | iv = &(export_iv1[iv_len]); | ||
419 | } | ||
420 | } | ||
421 | |||
422 | if (EVP_CIPHER_mode(cipher) == EVP_CIPH_GCM_MODE) { | ||
423 | EVP_CipherInit_ex(cipher_ctx, cipher, NULL, key, NULL, | ||
424 | !is_read); | ||
425 | EVP_CIPHER_CTX_ctrl(cipher_ctx, EVP_CTRL_GCM_SET_IV_FIXED, | ||
426 | iv_len, (unsigned char *)iv); | ||
427 | } else | ||
428 | EVP_CipherInit_ex(cipher_ctx, cipher, NULL, key, iv, !is_read); | ||
429 | |||
430 | /* Needed for "composite" AEADs, such as RC4-HMAC-MD5 */ | ||
431 | if ((EVP_CIPHER_flags(cipher) & EVP_CIPH_FLAG_AEAD_CIPHER) && | ||
432 | mac_secret_size) | ||
433 | EVP_CIPHER_CTX_ctrl(cipher_ctx, EVP_CTRL_AEAD_SET_MAC_KEY, | ||
434 | mac_secret_size, (unsigned char *)mac_secret); | ||
435 | |||
436 | if (is_export) { | ||
437 | OPENSSL_cleanse(export_tmp1, sizeof(export_tmp1)); | ||
438 | OPENSSL_cleanse(export_tmp2, sizeof(export_tmp2)); | ||
439 | OPENSSL_cleanse(export_iv1, sizeof(export_iv1)); | ||
440 | OPENSSL_cleanse(export_iv2, sizeof(export_iv2)); | ||
441 | } | ||
442 | |||
443 | return (1); | ||
444 | |||
445 | err: | ||
446 | SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE_CIPHER, ERR_R_MALLOC_FAILURE); | ||
447 | err2: | ||
448 | return (0); | ||
449 | } | ||
450 | |||
451 | int | ||
452 | tls1_change_cipher_state(SSL *s, int which) | ||
453 | { | ||
309 | const unsigned char *client_write_mac_secret, *server_write_mac_secret; | 454 | const unsigned char *client_write_mac_secret, *server_write_mac_secret; |
310 | const unsigned char *client_write_key, *server_write_key; | 455 | const unsigned char *client_write_key, *server_write_key; |
311 | const unsigned char *client_write_iv, *server_write_iv; | 456 | const unsigned char *client_write_iv, *server_write_iv; |
312 | const unsigned char *mac_secret, *key, *iv; | 457 | const unsigned char *mac_secret, *key, *iv; |
313 | int mac_secret_size, key_len, iv_len; | 458 | int mac_secret_size, key_len, iv_len; |
314 | unsigned char *key_block, *exp_label, *seq; | 459 | unsigned char *key_block, *seq; |
315 | |||
316 | EVP_CIPHER_CTX *cipher_ctx; | ||
317 | const EVP_CIPHER *cipher; | 460 | const EVP_CIPHER *cipher; |
461 | char is_read, use_client_keys; | ||
462 | int is_export; | ||
463 | |||
318 | #ifndef OPENSSL_NO_COMP | 464 | #ifndef OPENSSL_NO_COMP |
319 | const SSL_COMP *comp; | 465 | const SSL_COMP *comp; |
320 | #endif | 466 | #endif |
321 | const EVP_MD *mac; | ||
322 | int mac_type; | ||
323 | EVP_MD_CTX *mac_ctx; | ||
324 | EVP_PKEY *mac_key; | ||
325 | int is_export, exp_label_len; | ||
326 | char is_read, use_client_keys; | ||
327 | 467 | ||
328 | is_export = SSL_C_IS_EXPORT(s->s3->tmp.new_cipher); | 468 | is_export = SSL_C_IS_EXPORT(s->s3->tmp.new_cipher); |
329 | cipher = s->s3->tmp.new_sym_enc; | 469 | cipher = s->s3->tmp.new_sym_enc; |
330 | mac = s->s3->tmp.new_hash; | ||
331 | mac_type = s->s3->tmp.new_mac_pkey_type; | ||
332 | 470 | ||
333 | /* | 471 | /* |
334 | * is_read is true if we have just read a ChangeCipherSpec message, | 472 | * is_read is true if we have just read a ChangeCipherSpec message, |
@@ -381,51 +519,6 @@ tls1_change_cipher_state(SSL *s, int which) | |||
381 | } | 519 | } |
382 | #endif | 520 | #endif |
383 | 521 | ||
384 | if (is_read) { | ||
385 | if (s->s3->tmp.new_cipher->algorithm2 & TLS1_STREAM_MAC) | ||
386 | s->mac_flags |= SSL_MAC_FLAG_READ_MAC_STREAM; | ||
387 | else | ||
388 | s->mac_flags &= ~SSL_MAC_FLAG_READ_MAC_STREAM; | ||
389 | |||
390 | EVP_CIPHER_CTX_free(s->enc_read_ctx); | ||
391 | s->enc_read_ctx = NULL; | ||
392 | EVP_MD_CTX_destroy(s->read_hash); | ||
393 | s->read_hash = NULL; | ||
394 | |||
395 | if ((cipher_ctx = EVP_CIPHER_CTX_new()) == NULL) | ||
396 | goto err; | ||
397 | s->enc_read_ctx = cipher_ctx; | ||
398 | if ((mac_ctx = EVP_MD_CTX_create()) == NULL) | ||
399 | goto err; | ||
400 | s->read_hash = mac_ctx; | ||
401 | } else { | ||
402 | if (s->s3->tmp.new_cipher->algorithm2 & TLS1_STREAM_MAC) | ||
403 | s->mac_flags |= SSL_MAC_FLAG_WRITE_MAC_STREAM; | ||
404 | else | ||
405 | s->mac_flags &= ~SSL_MAC_FLAG_WRITE_MAC_STREAM; | ||
406 | |||
407 | /* | ||
408 | * DTLS fragments retain a pointer to the compression, cipher | ||
409 | * and hash contexts, so that it can restore state in order | ||
410 | * to perform retransmissions. As such, we cannot free write | ||
411 | * contexts that are used for DTLS - these are instead freed | ||
412 | * by DTLS when its frees a ChangeCipherSpec fragment. | ||
413 | */ | ||
414 | if (!SSL_IS_DTLS(s)) { | ||
415 | EVP_CIPHER_CTX_free(s->enc_write_ctx); | ||
416 | s->enc_write_ctx = NULL; | ||
417 | EVP_MD_CTX_destroy(s->write_hash); | ||
418 | s->write_hash = NULL; | ||
419 | } | ||
420 | if ((cipher_ctx = EVP_CIPHER_CTX_new()) == NULL) | ||
421 | goto err; | ||
422 | s->enc_write_ctx = cipher_ctx; | ||
423 | if ((mac_ctx = EVP_MD_CTX_create()) == NULL) | ||
424 | goto err; | ||
425 | s->write_hash = mac_ctx; | ||
426 | |||
427 | } | ||
428 | |||
429 | /* | 522 | /* |
430 | * Reset sequence number to zero - for DTLS this is handled in | 523 | * Reset sequence number to zero - for DTLS this is handled in |
431 | * dtls1_reset_seq_numbers(). | 524 | * dtls1_reset_seq_numbers(). |
@@ -486,74 +579,8 @@ tls1_change_cipher_state(SSL *s, int which) | |||
486 | s->s3->write_mac_secret_size = mac_secret_size; | 579 | s->s3->write_mac_secret_size = mac_secret_size; |
487 | } | 580 | } |
488 | 581 | ||
489 | if (!(EVP_CIPHER_flags(cipher) & EVP_CIPH_FLAG_AEAD_CIPHER)) { | 582 | return tls1_change_cipher_state_cipher(s, is_read, use_client_keys, |
490 | mac_key = EVP_PKEY_new_mac_key(mac_type, NULL, | 583 | mac_secret, mac_secret_size, key, key_len, iv, iv_len); |
491 | mac_secret, mac_secret_size); | ||
492 | if (mac_key == NULL) | ||
493 | goto err; | ||
494 | EVP_DigestSignInit(mac_ctx, NULL, mac, NULL, mac_key); | ||
495 | EVP_PKEY_free(mac_key); | ||
496 | } | ||
497 | |||
498 | if (is_export) { | ||
499 | /* | ||
500 | * Both the read and write key/iv are set to the same value | ||
501 | * since only the correct one will be used :-). | ||
502 | */ | ||
503 | if (use_client_keys) { | ||
504 | exp_label = TLS_MD_CLIENT_WRITE_KEY_CONST; | ||
505 | exp_label_len = TLS_MD_CLIENT_WRITE_KEY_CONST_SIZE; | ||
506 | } else { | ||
507 | exp_label = TLS_MD_SERVER_WRITE_KEY_CONST; | ||
508 | exp_label_len = TLS_MD_SERVER_WRITE_KEY_CONST_SIZE; | ||
509 | } | ||
510 | |||
511 | if (!tls1_PRF(ssl_get_algorithm2(s), | ||
512 | exp_label, exp_label_len, | ||
513 | s->s3->client_random, SSL3_RANDOM_SIZE, | ||
514 | s->s3->server_random, SSL3_RANDOM_SIZE, | ||
515 | NULL, 0, NULL, 0, key, key_len, export_tmp1, export_tmp2, | ||
516 | EVP_CIPHER_key_length(cipher))) | ||
517 | goto err2; | ||
518 | key = export_tmp1; | ||
519 | |||
520 | if (iv_len > 0) { | ||
521 | if (!tls1_PRF(ssl_get_algorithm2(s), | ||
522 | TLS_MD_IV_BLOCK_CONST, TLS_MD_IV_BLOCK_CONST_SIZE, | ||
523 | s->s3->client_random, SSL3_RANDOM_SIZE, | ||
524 | s->s3->server_random, SSL3_RANDOM_SIZE, | ||
525 | NULL, 0, NULL, 0, empty, 0, | ||
526 | export_iv1, export_iv2, iv_len * 2)) | ||
527 | goto err2; | ||
528 | if (use_client_keys) | ||
529 | iv = export_iv1; | ||
530 | else | ||
531 | iv = &(export_iv1[iv_len]); | ||
532 | } | ||
533 | } | ||
534 | |||
535 | if (EVP_CIPHER_mode(cipher) == EVP_CIPH_GCM_MODE) { | ||
536 | EVP_CipherInit_ex(cipher_ctx, cipher, NULL, key, NULL, | ||
537 | !is_read); | ||
538 | EVP_CIPHER_CTX_ctrl(cipher_ctx, EVP_CTRL_GCM_SET_IV_FIXED, | ||
539 | iv_len, (unsigned char *)iv); | ||
540 | } else | ||
541 | EVP_CipherInit_ex(cipher_ctx, cipher, NULL, key, iv, !is_read); | ||
542 | |||
543 | /* Needed for "composite" AEADs, such as RC4-HMAC-MD5 */ | ||
544 | if ((EVP_CIPHER_flags(cipher) & EVP_CIPH_FLAG_AEAD_CIPHER) && | ||
545 | mac_secret_size) | ||
546 | EVP_CIPHER_CTX_ctrl(cipher_ctx, EVP_CTRL_AEAD_SET_MAC_KEY, | ||
547 | mac_secret_size, (unsigned char *)mac_secret); | ||
548 | |||
549 | if (is_export) { | ||
550 | OPENSSL_cleanse(export_tmp1, sizeof(export_tmp1)); | ||
551 | OPENSSL_cleanse(export_tmp2, sizeof(export_tmp2)); | ||
552 | OPENSSL_cleanse(export_iv1, sizeof(export_iv1)); | ||
553 | OPENSSL_cleanse(export_iv2, sizeof(export_iv2)); | ||
554 | } | ||
555 | |||
556 | return (1); | ||
557 | 584 | ||
558 | err: | 585 | err: |
559 | SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE, ERR_R_MALLOC_FAILURE); | 586 | SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE, ERR_R_MALLOC_FAILURE); |