diff --git a/src/crypto/mishmash/aes_gcm_sha256.c b/src/crypto/mishmash/aes_gcm_sha256.c index 57868cd41..68dae5fc1 100644 --- a/src/crypto/mishmash/aes_gcm_sha256.c +++ b/src/crypto/mishmash/aes_gcm_sha256.c @@ -36,6 +36,7 @@ struct tls_cipher_suite tls_aes_128_gcm_sha256 __tls_cipher_suite ( 31 ) = { .fixed_iv_len = 12, .record_iv_len = 0, .mac_len = 0, + .verify_len = SHA256_DIGEST_SIZE, .flags = TLS_CIPHER_FL_SEQUENTIAL_IV, .exchange = &tls_null_exchange_algorithm, .pubkey = &pubkey_null, diff --git a/src/crypto/mishmash/aes_gcm_sha384.c b/src/crypto/mishmash/aes_gcm_sha384.c index d7196ba88..9c066a9cb 100644 --- a/src/crypto/mishmash/aes_gcm_sha384.c +++ b/src/crypto/mishmash/aes_gcm_sha384.c @@ -36,6 +36,7 @@ struct tls_cipher_suite tls_aes_256_gcm_sha384 __tls_cipher_suite ( 32 ) = { .fixed_iv_len = 12, .record_iv_len = 0, .mac_len = 0, + .verify_len = SHA384_DIGEST_SIZE, .flags = TLS_CIPHER_FL_SEQUENTIAL_IV, .exchange = &tls_null_exchange_algorithm, .pubkey = &pubkey_null, diff --git a/src/crypto/mishmash/dhe_rsa_aes_cbc_sha1.c b/src/crypto/mishmash/dhe_rsa_aes_cbc_sha1.c index 8ae747d81..252e52c06 100644 --- a/src/crypto/mishmash/dhe_rsa_aes_cbc_sha1.c +++ b/src/crypto/mishmash/dhe_rsa_aes_cbc_sha1.c @@ -39,6 +39,7 @@ tls_dhe_rsa_with_aes_128_cbc_sha __tls_cipher_suite ( 15 ) = { .fixed_iv_len = 0, .record_iv_len = AES_BLOCKSIZE, .mac_len = SHA1_DIGEST_SIZE, + .verify_len = 12, .flags = 0, .exchange = &tls_dhe_exchange_algorithm, .pubkey = &rsa_algorithm, @@ -55,6 +56,7 @@ tls_dhe_rsa_with_aes_256_cbc_sha __tls_cipher_suite ( 16 ) = { .fixed_iv_len = 0, .record_iv_len = AES_BLOCKSIZE, .mac_len = SHA1_DIGEST_SIZE, + .verify_len = 12, .flags = 0, .exchange = &tls_dhe_exchange_algorithm, .pubkey = &rsa_algorithm, diff --git a/src/crypto/mishmash/dhe_rsa_aes_cbc_sha256.c b/src/crypto/mishmash/dhe_rsa_aes_cbc_sha256.c index 4358352ed..995f36188 100644 --- a/src/crypto/mishmash/dhe_rsa_aes_cbc_sha256.c +++ b/src/crypto/mishmash/dhe_rsa_aes_cbc_sha256.c @@ -38,6 +38,7 @@ tls_dhe_rsa_with_aes_128_cbc_sha256 __tls_cipher_suite ( 13 ) = { .fixed_iv_len = 0, .record_iv_len = AES_BLOCKSIZE, .mac_len = SHA256_DIGEST_SIZE, + .verify_len = 12, .flags = 0, .exchange = &tls_dhe_exchange_algorithm, .pubkey = &rsa_algorithm, @@ -54,6 +55,7 @@ tls_dhe_rsa_with_aes_256_cbc_sha256 __tls_cipher_suite ( 14 ) = { .fixed_iv_len = 0, .record_iv_len = AES_BLOCKSIZE, .mac_len = SHA256_DIGEST_SIZE, + .verify_len = 12, .flags = 0, .exchange = &tls_dhe_exchange_algorithm, .pubkey = &rsa_algorithm, diff --git a/src/crypto/mishmash/dhe_rsa_aes_gcm_sha256.c b/src/crypto/mishmash/dhe_rsa_aes_gcm_sha256.c index 7a640e8b8..298f6551b 100644 --- a/src/crypto/mishmash/dhe_rsa_aes_gcm_sha256.c +++ b/src/crypto/mishmash/dhe_rsa_aes_gcm_sha256.c @@ -38,6 +38,7 @@ tls_dhe_rsa_with_aes_128_gcm_sha256 __tls_cipher_suite ( 11 ) = { .fixed_iv_len = 4, .record_iv_len = 8, .mac_len = 0, + .verify_len = 12, .flags = TLS_CIPHER_FL_SEQUENTIAL_IV, .exchange = &tls_dhe_exchange_algorithm, .pubkey = &rsa_algorithm, diff --git a/src/crypto/mishmash/dhe_rsa_aes_gcm_sha384.c b/src/crypto/mishmash/dhe_rsa_aes_gcm_sha384.c index 9ec151e33..2f774c6d4 100644 --- a/src/crypto/mishmash/dhe_rsa_aes_gcm_sha384.c +++ b/src/crypto/mishmash/dhe_rsa_aes_gcm_sha384.c @@ -38,6 +38,7 @@ tls_dhe_rsa_with_aes_256_gcm_sha384 __tls_cipher_suite ( 12 ) = { .fixed_iv_len = 4, .record_iv_len = 8, .mac_len = 0, + .verify_len = 12, .flags = TLS_CIPHER_FL_SEQUENTIAL_IV, .exchange = &tls_dhe_exchange_algorithm, .pubkey = &rsa_algorithm, diff --git a/src/crypto/mishmash/ecdhe_ecdsa_aes_cbc_sha1.c b/src/crypto/mishmash/ecdhe_ecdsa_aes_cbc_sha1.c index 81826a448..f3d213da3 100644 --- a/src/crypto/mishmash/ecdhe_ecdsa_aes_cbc_sha1.c +++ b/src/crypto/mishmash/ecdhe_ecdsa_aes_cbc_sha1.c @@ -39,6 +39,7 @@ tls_ecdhe_ecdsa_with_aes_128_cbc_sha __tls_cipher_suite ( 05 ) = { .fixed_iv_len = 0, .record_iv_len = AES_BLOCKSIZE, .mac_len = SHA1_DIGEST_SIZE, + .verify_len = 12, .flags = 0, .exchange = &tls_ecdhe_exchange_algorithm, .pubkey = &ecdsa_algorithm, @@ -55,6 +56,7 @@ tls_ecdhe_ecdsa_with_aes_256_cbc_sha __tls_cipher_suite ( 06 ) = { .fixed_iv_len = 0, .record_iv_len = AES_BLOCKSIZE, .mac_len = SHA1_DIGEST_SIZE, + .verify_len = 12, .flags = 0, .exchange = &tls_ecdhe_exchange_algorithm, .pubkey = &ecdsa_algorithm, diff --git a/src/crypto/mishmash/ecdhe_ecdsa_aes_cbc_sha256.c b/src/crypto/mishmash/ecdhe_ecdsa_aes_cbc_sha256.c index ecb2e5dc2..634e1f1c1 100644 --- a/src/crypto/mishmash/ecdhe_ecdsa_aes_cbc_sha256.c +++ b/src/crypto/mishmash/ecdhe_ecdsa_aes_cbc_sha256.c @@ -38,6 +38,7 @@ tls_ecdhe_ecdsa_with_aes_128_cbc_sha256 __tls_cipher_suite ( 03 ) = { .fixed_iv_len = 0, .record_iv_len = AES_BLOCKSIZE, .mac_len = SHA256_DIGEST_SIZE, + .verify_len = 12, .flags = 0, .exchange = &tls_ecdhe_exchange_algorithm, .pubkey = &ecdsa_algorithm, diff --git a/src/crypto/mishmash/ecdhe_ecdsa_aes_cbc_sha384.c b/src/crypto/mishmash/ecdhe_ecdsa_aes_cbc_sha384.c index 50aa51d1c..494a3855f 100644 --- a/src/crypto/mishmash/ecdhe_ecdsa_aes_cbc_sha384.c +++ b/src/crypto/mishmash/ecdhe_ecdsa_aes_cbc_sha384.c @@ -38,6 +38,7 @@ tls_ecdhe_ecdsa_with_aes_256_cbc_sha384 __tls_cipher_suite ( 04 ) = { .fixed_iv_len = 0, .record_iv_len = AES_BLOCKSIZE, .mac_len = SHA384_DIGEST_SIZE, + .verify_len = 12, .flags = 0, .exchange = &tls_ecdhe_exchange_algorithm, .pubkey = &ecdsa_algorithm, diff --git a/src/crypto/mishmash/ecdhe_ecdsa_aes_gcm_sha256.c b/src/crypto/mishmash/ecdhe_ecdsa_aes_gcm_sha256.c index ebfca3c8c..df8f642f0 100644 --- a/src/crypto/mishmash/ecdhe_ecdsa_aes_gcm_sha256.c +++ b/src/crypto/mishmash/ecdhe_ecdsa_aes_gcm_sha256.c @@ -38,6 +38,7 @@ tls_ecdhe_ecdsa_with_aes_128_gcm_sha256 __tls_cipher_suite ( 01 ) = { .fixed_iv_len = 4, .record_iv_len = 8, .mac_len = 0, + .verify_len = 12, .flags = TLS_CIPHER_FL_SEQUENTIAL_IV, .exchange = &tls_ecdhe_exchange_algorithm, .pubkey = &ecdsa_algorithm, diff --git a/src/crypto/mishmash/ecdhe_ecdsa_aes_gcm_sha384.c b/src/crypto/mishmash/ecdhe_ecdsa_aes_gcm_sha384.c index 18c9275f7..029b6fd59 100644 --- a/src/crypto/mishmash/ecdhe_ecdsa_aes_gcm_sha384.c +++ b/src/crypto/mishmash/ecdhe_ecdsa_aes_gcm_sha384.c @@ -38,6 +38,7 @@ tls_ecdhe_ecdsa_with_aes_256_gcm_sha384 __tls_cipher_suite ( 02 ) = { .fixed_iv_len = 4, .record_iv_len = 8, .mac_len = 0, + .verify_len = 12, .flags = TLS_CIPHER_FL_SEQUENTIAL_IV, .exchange = &tls_ecdhe_exchange_algorithm, .pubkey = &ecdsa_algorithm, diff --git a/src/crypto/mishmash/ecdhe_rsa_aes_cbc_sha1.c b/src/crypto/mishmash/ecdhe_rsa_aes_cbc_sha1.c index 224097168..23e606c77 100644 --- a/src/crypto/mishmash/ecdhe_rsa_aes_cbc_sha1.c +++ b/src/crypto/mishmash/ecdhe_rsa_aes_cbc_sha1.c @@ -39,6 +39,7 @@ tls_ecdhe_rsa_with_aes_128_cbc_sha __tls_cipher_suite ( 05 ) = { .fixed_iv_len = 0, .record_iv_len = AES_BLOCKSIZE, .mac_len = SHA1_DIGEST_SIZE, + .verify_len = 12, .flags = 0, .exchange = &tls_ecdhe_exchange_algorithm, .pubkey = &rsa_algorithm, @@ -55,6 +56,7 @@ tls_ecdhe_rsa_with_aes_256_cbc_sha __tls_cipher_suite ( 06 ) = { .fixed_iv_len = 0, .record_iv_len = AES_BLOCKSIZE, .mac_len = SHA1_DIGEST_SIZE, + .verify_len = 12, .flags = 0, .exchange = &tls_ecdhe_exchange_algorithm, .pubkey = &rsa_algorithm, diff --git a/src/crypto/mishmash/ecdhe_rsa_aes_cbc_sha256.c b/src/crypto/mishmash/ecdhe_rsa_aes_cbc_sha256.c index 93ada644e..6f31b6c9e 100644 --- a/src/crypto/mishmash/ecdhe_rsa_aes_cbc_sha256.c +++ b/src/crypto/mishmash/ecdhe_rsa_aes_cbc_sha256.c @@ -38,6 +38,7 @@ tls_ecdhe_rsa_with_aes_128_cbc_sha256 __tls_cipher_suite ( 03 ) = { .fixed_iv_len = 0, .record_iv_len = AES_BLOCKSIZE, .mac_len = SHA256_DIGEST_SIZE, + .verify_len = 12, .flags = 0, .exchange = &tls_ecdhe_exchange_algorithm, .pubkey = &rsa_algorithm, diff --git a/src/crypto/mishmash/ecdhe_rsa_aes_cbc_sha384.c b/src/crypto/mishmash/ecdhe_rsa_aes_cbc_sha384.c index 166ae73b0..c0bd657c8 100644 --- a/src/crypto/mishmash/ecdhe_rsa_aes_cbc_sha384.c +++ b/src/crypto/mishmash/ecdhe_rsa_aes_cbc_sha384.c @@ -38,6 +38,7 @@ tls_ecdhe_rsa_with_aes_256_cbc_sha384 __tls_cipher_suite ( 04 ) = { .fixed_iv_len = 0, .record_iv_len = AES_BLOCKSIZE, .mac_len = SHA384_DIGEST_SIZE, + .verify_len = 12, .flags = 0, .exchange = &tls_ecdhe_exchange_algorithm, .pubkey = &rsa_algorithm, diff --git a/src/crypto/mishmash/ecdhe_rsa_aes_gcm_sha256.c b/src/crypto/mishmash/ecdhe_rsa_aes_gcm_sha256.c index 785670bcc..56e644aba 100644 --- a/src/crypto/mishmash/ecdhe_rsa_aes_gcm_sha256.c +++ b/src/crypto/mishmash/ecdhe_rsa_aes_gcm_sha256.c @@ -38,6 +38,7 @@ tls_ecdhe_rsa_with_aes_128_gcm_sha256 __tls_cipher_suite ( 01 ) = { .fixed_iv_len = 4, .record_iv_len = 8, .mac_len = 0, + .verify_len = 12, .flags = TLS_CIPHER_FL_SEQUENTIAL_IV, .exchange = &tls_ecdhe_exchange_algorithm, .pubkey = &rsa_algorithm, diff --git a/src/crypto/mishmash/ecdhe_rsa_aes_gcm_sha384.c b/src/crypto/mishmash/ecdhe_rsa_aes_gcm_sha384.c index d6da45c81..07860867f 100644 --- a/src/crypto/mishmash/ecdhe_rsa_aes_gcm_sha384.c +++ b/src/crypto/mishmash/ecdhe_rsa_aes_gcm_sha384.c @@ -38,6 +38,7 @@ tls_ecdhe_rsa_with_aes_256_gcm_sha384 __tls_cipher_suite ( 02 ) = { .fixed_iv_len = 4, .record_iv_len = 8, .mac_len = 0, + .verify_len = 12, .flags = TLS_CIPHER_FL_SEQUENTIAL_IV, .exchange = &tls_ecdhe_exchange_algorithm, .pubkey = &rsa_algorithm, diff --git a/src/crypto/mishmash/rsa_aes_cbc_sha1.c b/src/crypto/mishmash/rsa_aes_cbc_sha1.c index 17ca9c2f7..b89a4cc2c 100644 --- a/src/crypto/mishmash/rsa_aes_cbc_sha1.c +++ b/src/crypto/mishmash/rsa_aes_cbc_sha1.c @@ -39,6 +39,7 @@ tls_rsa_with_aes_128_cbc_sha __tls_cipher_suite ( 25 ) = { .fixed_iv_len = 0, .record_iv_len = AES_BLOCKSIZE, .mac_len = SHA1_DIGEST_SIZE, + .verify_len = 12, .flags = 0, .exchange = &tls_pubkey_exchange_algorithm, .pubkey = &rsa_algorithm, @@ -55,6 +56,7 @@ tls_rsa_with_aes_256_cbc_sha __tls_cipher_suite ( 26 ) = { .fixed_iv_len = 0, .record_iv_len = AES_BLOCKSIZE, .mac_len = SHA1_DIGEST_SIZE, + .verify_len = 12, .flags = 0, .exchange = &tls_pubkey_exchange_algorithm, .pubkey = &rsa_algorithm, diff --git a/src/crypto/mishmash/rsa_aes_cbc_sha256.c b/src/crypto/mishmash/rsa_aes_cbc_sha256.c index f02dd2fd8..07074d427 100644 --- a/src/crypto/mishmash/rsa_aes_cbc_sha256.c +++ b/src/crypto/mishmash/rsa_aes_cbc_sha256.c @@ -38,6 +38,7 @@ tls_rsa_with_aes_128_cbc_sha256 __tls_cipher_suite ( 23 ) = { .fixed_iv_len = 0, .record_iv_len = AES_BLOCKSIZE, .mac_len = SHA256_DIGEST_SIZE, + .verify_len = 12, .flags = 0, .exchange = &tls_pubkey_exchange_algorithm, .pubkey = &rsa_algorithm, @@ -54,6 +55,7 @@ tls_rsa_with_aes_256_cbc_sha256 __tls_cipher_suite ( 24 ) = { .fixed_iv_len = 0, .record_iv_len = AES_BLOCKSIZE, .mac_len = SHA256_DIGEST_SIZE, + .verify_len = 12, .flags = 0, .exchange = &tls_pubkey_exchange_algorithm, .pubkey = &rsa_algorithm, diff --git a/src/crypto/mishmash/rsa_aes_gcm_sha256.c b/src/crypto/mishmash/rsa_aes_gcm_sha256.c index ac687b7cc..1bc23ce36 100644 --- a/src/crypto/mishmash/rsa_aes_gcm_sha256.c +++ b/src/crypto/mishmash/rsa_aes_gcm_sha256.c @@ -38,6 +38,7 @@ tls_rsa_with_aes_128_gcm_sha256 __tls_cipher_suite ( 21 ) = { .fixed_iv_len = 4, .record_iv_len = 8, .mac_len = 0, + .verify_len = 12, .flags = TLS_CIPHER_FL_SEQUENTIAL_IV, .exchange = &tls_pubkey_exchange_algorithm, .pubkey = &rsa_algorithm, diff --git a/src/crypto/mishmash/rsa_aes_gcm_sha384.c b/src/crypto/mishmash/rsa_aes_gcm_sha384.c index c9b88d8c4..039f8321d 100644 --- a/src/crypto/mishmash/rsa_aes_gcm_sha384.c +++ b/src/crypto/mishmash/rsa_aes_gcm_sha384.c @@ -38,6 +38,7 @@ tls_rsa_with_aes_256_gcm_sha384 __tls_cipher_suite ( 22 ) = { .fixed_iv_len = 4, .record_iv_len = 8, .mac_len = 0, + .verify_len = 12, .flags = TLS_CIPHER_FL_SEQUENTIAL_IV, .exchange = &tls_pubkey_exchange_algorithm, .pubkey = &rsa_algorithm, diff --git a/src/include/ipxe/tls.h b/src/include/ipxe/tls.h index 0d1be7699..e3f4b4455 100644 --- a/src/include/ipxe/tls.h +++ b/src/include/ipxe/tls.h @@ -196,14 +196,6 @@ struct tls_auth_header { struct tls_header header; } __attribute__ (( packed )); -/** TLS verification data */ -struct tls_verify_data { - /** Client verification data */ - uint8_t client[12]; - /** Server verification data */ - uint8_t server[12]; -} __attribute__ (( packed )); - /** TLS RX state machine state */ enum tls_rx_state { TLS_RX_HEADER = 0, @@ -283,6 +275,8 @@ struct tls_cipher_suite { uint8_t record_iv_len; /** MAC length */ uint8_t mac_len; + /** Verification data length */ + uint8_t verify_len; /** Flags */ uint8_t flags; }; @@ -415,6 +409,16 @@ struct tls_session { struct list_head conn; }; +/** TLS verification data */ +struct tls_verify_data { + /** Dynamically allocated storage */ + void *dynamic; + /** Client verification data */ + void *client; + /** Server verification data */ + void *server; +}; + /** TLS transmit state */ struct tls_tx { /** Cipher specification */ diff --git a/src/net/tls.c b/src/net/tls.c index 6fceb3e9c..f4df75862 100644 --- a/src/net/tls.c +++ b/src/net/tls.c @@ -411,6 +411,7 @@ static void free_tls ( struct refcnt *refcnt ) { /* Free dynamically-allocated resources */ zfree ( tls->new_ticket.data ); tls_clear_digest ( tls ); + free ( tls->verify.dynamic ); tls_clear_cipher ( tls, &tls->tx.cipherspec ); tls_clear_cipher ( tls, &tls->rx.cipherspec ); list_for_each_entry_safe ( iobuf, tmp, &tls->rx.data, list ) { @@ -649,6 +650,38 @@ tls_find_cipher_suite ( unsigned int cipher_suite ) { return NULL; } +/** + * Set verification data length + * + * @v tls TLS connection + * @v verify_len Verification data length + * @ret rc Return status code + */ +static int tls_set_verify_len ( struct tls_connection *tls, + size_t verify_len ) { + struct tls_verify_data *verify = &tls->verify; + size_t total; + void *dynamic; + + /* Free any existing dynamically allocated storage */ + free ( verify->dynamic ); + memset ( verify, 0, sizeof ( *verify ) ); + + /* Allocate dynamic storage */ + total = ( verify_len * 2 ); + dynamic = zalloc ( total ); + if ( ! dynamic ) + return -ENOMEM; + + /* Assign storage */ + verify->dynamic = dynamic; + verify->client = dynamic; dynamic += verify_len; + verify->server = dynamic; dynamic += verify_len; + assert ( ( verify->dynamic + total ) == dynamic ); + + return 0; +} + /** * Select cipher suite * @@ -694,6 +727,10 @@ static int tls_select_cipher ( struct tls_connection *tls, if ( ( rc = tls_client_hello ( tls, tls_add_handshake ) ) != 0 ) return rc; + /* Set verification data length */ + if ( ( rc = tls_set_verify_len ( tls, suite->verify_len ) ) != 0 ) + return rc; + /* Set default named group */ tls->group = suite->exchange->group; @@ -1510,10 +1547,11 @@ static int tls_channel_verify ( struct secure_channel *channel, const void *auth, size_t len ) { struct tls_connection *tls = container_of ( channel, struct tls_connection, channel ); + struct tls_cipher_suite *suite = tls->suite; int rc; /* Sanity checks */ - if ( len != sizeof ( tls->verify.server ) ) { + if ( ( len == 0 ) || ( len != suite->verify_len ) ) { DBGC ( tls, "TLS %p invalid authenticator value:\n", tls ); DBGC_HDA ( tls, 0, auth, len ); return -EPERM_VERIFY; @@ -1521,8 +1559,7 @@ static int tls_channel_verify ( struct secure_channel *channel, /* Generate verification data */ if ( ( rc = tlskey_verify ( &tls->key, &tls_server, - tls->verify.server, - sizeof ( tls->verify.server ) ) ) != 0 ) { + tls->verify.server, len ) ) != 0 ) { DBGC ( tls, "TLS %p could not generate server verification: " "%s\n", tls, strerror ( rc ) ); return rc; @@ -1784,7 +1821,7 @@ static int tls_client_hello ( struct tls_connection *tls, struct tls_session *session = tls->session; size_t name_len = strlen ( session->name ); size_t reneg_len = ( tls->secure_renegotiation ? - sizeof ( tls->verify.client ) : 0 ); + tls->suite->verify_len : 0 ); size_t pubsize = tls->group->exchange->pubsize; unsigned int has_key_share_key = ( tls->group->code ? 1 : 0 ); unsigned int has_named_group = ( TLS_NUM_NAMED_GROUPS ? 1 : 0 ); @@ -2308,16 +2345,17 @@ static int tls_send_change_cipher ( struct tls_connection *tls ) { * @ret rc Return status code */ static int tls_send_finished ( struct tls_connection *tls ) { + struct tls_cipher_suite *suite = tls->suite; + size_t verify_len = suite->verify_len; struct { uint32_t type_length; - uint8_t verify_data[ sizeof ( tls->verify.client ) ]; + uint8_t verify_data[verify_len]; } __attribute__ (( packed )) finished; int rc; /* Construct client verification data */ - if ( ( rc = tlskey_verify ( &tls->key, &tls_client, - tls->verify.client, - sizeof ( tls->verify.client ) ) ) != 0 ) { + if ( ( rc = tlskey_verify ( &tls->key, &tls_client, tls->verify.client, + verify_len ) ) != 0 ) { DBGC ( tls, "TLS %p could not generate client verification: " "%s\n", tls, strerror ( rc ) ); return rc; @@ -2328,8 +2366,7 @@ static int tls_send_finished ( struct tls_connection *tls ) { finished.type_length = ( cpu_to_le32 ( TLS_FINISHED ) | htonl ( sizeof ( finished ) - sizeof ( finished.type_length ) ) ); - memcpy ( finished.verify_data, tls->verify.client, - sizeof ( finished.verify_data ) ); + memcpy ( finished.verify_data, tls->verify.client, verify_len ); /* Transmit record */ if ( ( rc = tls_send_handshake ( tls, &finished, @@ -2540,6 +2577,7 @@ static int tls_new_server_hello ( struct tls_connection *tls, size_t session_id_len; size_t exts_len; size_t ext_len; + size_t verify_len; size_t remaining; int rc; @@ -2673,6 +2711,31 @@ static int tls_new_server_hello ( struct tls_connection *tls, return -EPERM_DOWNGRADE; } + /* Handle secure renegotiation */ + if ( tls->secure_renegotiation ) { + + /* Secure renegotiation is expected; verify data */ + verify_len = ( 2 * tls->suite->verify_len ); + if ( ( reneg == NULL ) || + ( reneg->len != verify_len ) || + ( memcmp ( reneg->data, tls->verify.dynamic, + verify_len ) != 0 ) ) { + DBGC ( tls, "TLS %p server failed secure " + "renegotiation\n", tls ); + return -EPERM_RENEG_VERIFY; + } + + } else if ( reneg != NULL ) { + + /* Secure renegotiation is being enabled */ + if ( reneg->len != 0 ) { + DBGC ( tls, "TLS %p server provided non-empty initial " + "renegotiation\n", tls ); + return -EPERM_RENEG_VERIFY; + } + tls->secure_renegotiation = 1; + } + /* Select cipher suite */ if ( ( rc = tls_select_cipher ( tls, hello_b->cipher_suite ) ) != 0 ) return rc; @@ -2710,30 +2773,6 @@ static int tls_new_server_hello ( struct tls_connection *tls, } } - /* Handle secure renegotiation */ - if ( tls->secure_renegotiation ) { - - /* Secure renegotiation is expected; verify data */ - if ( ( reneg == NULL ) || - ( reneg->len != sizeof ( tls->verify ) ) || - ( memcmp ( reneg->data, &tls->verify, - sizeof ( tls->verify ) ) != 0 ) ) { - DBGC ( tls, "TLS %p server failed secure " - "renegotiation\n", tls ); - return -EPERM_RENEG_VERIFY; - } - - } else if ( reneg != NULL ) { - - /* Secure renegotiation is being enabled */ - if ( reneg->len != 0 ) { - DBGC ( tls, "TLS %p server provided non-empty initial " - "renegotiation\n", tls ); - return -EPERM_RENEG_VERIFY; - } - tls->secure_renegotiation = 1; - } - /* Select named group, if applicable */ if ( key ) { tls->group = tls_find_named_group ( key->code );