From 57504353febc61533e637f16ec6f933870b68ec9 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Sun, 12 Oct 2025 22:29:33 +0100 Subject: [PATCH] [tls] Refuse to resume sessions with mismatched master secret methods RFC 7627 section 5.3 states that the client must abort the handshake if the server attempts to resume a session where the master secret calculation method stored in the session does not match the method used for the connection being resumed. Signed-off-by: Michael Brown --- src/include/ipxe/tls.h | 2 ++ src/net/tls.c | 13 +++++++++++++ 2 files changed, 15 insertions(+) diff --git a/src/include/ipxe/tls.h b/src/include/ipxe/tls.h index 658a008f8..8ddc9c1be 100644 --- a/src/include/ipxe/tls.h +++ b/src/include/ipxe/tls.h @@ -353,6 +353,8 @@ struct tls_session { size_t ticket_len; /** Master secret */ uint8_t master_secret[48]; + /** Extended master secret flag */ + int extended_master_secret; /** List of connections */ struct list_head conn; diff --git a/src/net/tls.c b/src/net/tls.c index 8f91da018..efecf368c 100644 --- a/src/net/tls.c +++ b/src/net/tls.c @@ -183,6 +183,10 @@ FILE_LICENCE ( GPL2_OR_LATER ); #define EINFO_EPERM_KEY_EXCHANGE \ __einfo_uniqify ( EINFO_EPERM, 0x06, \ "ServerKeyExchange verification failed" ) +#define EPERM_EMS __einfo_error ( EINFO_EPERM_EMS ) +#define EINFO_EPERM_EMS \ + __einfo_uniqify ( EINFO_EPERM, 0x07, \ + "Extended master secret extension mismatch" ) #define EPROTO_VERSION __einfo_error ( EINFO_EPROTO_VERSION ) #define EINFO_EPROTO_VERSION \ __einfo_uniqify ( EINFO_EPROTO, 0x01, \ @@ -2243,6 +2247,14 @@ static int tls_new_server_hello ( struct tls_connection *tls, if ( ( rc = tls_generate_keys ( tls ) ) != 0 ) return rc; + /* Ensure master secret generation method matches */ + if ( tls->extended_master_secret != + tls->session->extended_master_secret ) { + DBGC ( tls, "TLS %p mismatched extended master secret " + "extension\n", tls ); + return -EPERM_EMS; + } + } else { /* Record new session ID, if present */ @@ -2635,6 +2647,7 @@ static int tls_new_finished ( struct tls_connection *tls, if ( tls->session_id_len || tls->new_session_ticket_len ) { memcpy ( session->master_secret, tls->master_secret, sizeof ( session->master_secret ) ); + session->extended_master_secret = tls->extended_master_secret; } if ( tls->session_id_len ) { session->id_len = tls->session_id_len; -- 2.47.3