Skip to content

Commit ab64bc5

Browse files
committed
[tls] Add support for the Extended Master Secret
RFC 7627 defines the Extended Master Secret (EMS) as an alternative calculation that uses the digest of all handshake messages rather than just the client and server random bytes. Add support for negotiating the Extended Master Secret extension and performing the relevant calculation of the master secret. Signed-off-by: Michael Brown <[email protected]>
1 parent d665610 commit ab64bc5

File tree

2 files changed

+55
-7
lines changed

2 files changed

+55
-7
lines changed

src/include/ipxe/tls.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,9 @@ struct tls_header {
134134
/* TLS signature algorithms extension */
135135
#define TLS_SIGNATURE_ALGORITHMS 13
136136

137+
/* TLS extended master secret extension */
138+
#define TLS_EXTENDED_MASTER_SECRET 23
139+
137140
/* TLS session ticket extension */
138141
#define TLS_SESSION_TICKET 35
139142

@@ -452,6 +455,8 @@ struct tls_connection {
452455
uint8_t *handshake_ctx;
453456
/** Secure renegotiation flag */
454457
int secure_renegotiation;
458+
/** Extended master secret flag */
459+
int extended_master_secret;
455460
/** Verification data */
456461
struct tls_verify_data verify;
457462

src/net/tls.c

Lines changed: 50 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,7 @@ static int tls_send_plaintext ( struct tls_connection *tls, unsigned int type,
200200
const void *data, size_t len );
201201
static void tls_clear_cipher ( struct tls_connection *tls,
202202
struct tls_cipherspec *cipherspec );
203+
static void tls_verify_handshake ( struct tls_connection *tls, void *out );
203204

204205
/******************************************************************************
205206
*
@@ -637,21 +638,43 @@ static void tls_prf ( struct tls_connection *tls, const void *secret,
637638
static void tls_generate_master_secret ( struct tls_connection *tls,
638639
const void *pre_master_secret,
639640
size_t pre_master_secret_len ) {
641+
struct digest_algorithm *digest = tls->handshake_digest;
642+
uint8_t digest_out[ digest->digestsize ];
643+
644+
/* Generate handshake digest */
645+
tls_verify_handshake ( tls, digest_out );
640646

641-
DBGC ( tls, "TLS %p pre-master-secret:\n", tls );
647+
/* Show inputs */
648+
DBGC ( tls, "TLS %p pre-master secret:\n", tls );
642649
DBGC_HD ( tls, pre_master_secret, pre_master_secret_len );
643650
DBGC ( tls, "TLS %p client random bytes:\n", tls );
644651
DBGC_HD ( tls, &tls->client.random, sizeof ( tls->client.random ) );
645652
DBGC ( tls, "TLS %p server random bytes:\n", tls );
646653
DBGC_HD ( tls, &tls->server.random, sizeof ( tls->server.random ) );
654+
DBGC ( tls, "TLS %p session hash:\n", tls );
655+
DBGC_HD ( tls, digest_out, sizeof ( digest_out ) );
647656

648-
tls_prf_label ( tls, pre_master_secret, pre_master_secret_len,
649-
&tls->master_secret, sizeof ( tls->master_secret ),
650-
"master secret",
651-
&tls->client.random, sizeof ( tls->client.random ),
652-
&tls->server.random, sizeof ( tls->server.random ) );
657+
/* Generate master secret */
658+
if ( tls->extended_master_secret ) {
659+
tls_prf_label ( tls, pre_master_secret, pre_master_secret_len,
660+
&tls->master_secret,
661+
sizeof ( tls->master_secret ),
662+
"extended master secret",
663+
digest_out, sizeof ( digest_out ) );
664+
} else {
665+
tls_prf_label ( tls, pre_master_secret, pre_master_secret_len,
666+
&tls->master_secret,
667+
sizeof ( tls->master_secret ),
668+
"master secret",
669+
&tls->client.random,
670+
sizeof ( tls->client.random ),
671+
&tls->server.random,
672+
sizeof ( tls->server.random ) );
673+
}
653674

654-
DBGC ( tls, "TLS %p generated master secret:\n", tls );
675+
/* Show output */
676+
DBGC ( tls, "TLS %p generated %smaster secret:\n", tls,
677+
( tls->extended_master_secret ? "extended ": "" ) );
655678
DBGC_HD ( tls, &tls->master_secret, sizeof ( tls->master_secret ) );
656679
}
657680

@@ -1195,12 +1218,17 @@ static int tls_client_hello ( struct tls_connection *tls,
11951218
uint16_t code[TLS_NUM_NAMED_CURVES];
11961219
} __attribute__ (( packed )) data;
11971220
} __attribute__ (( packed )) *named_curve_ext;
1221+
struct {
1222+
uint16_t type;
1223+
uint16_t len;
1224+
} __attribute__ (( packed )) *extended_master_secret_ext;
11981225
struct {
11991226
typeof ( *server_name_ext ) server_name;
12001227
typeof ( *max_fragment_length_ext ) max_fragment_length;
12011228
typeof ( *signature_algorithms_ext ) signature_algorithms;
12021229
typeof ( *renegotiation_info_ext ) renegotiation_info;
12031230
typeof ( *session_ticket_ext ) session_ticket;
1231+
typeof ( *extended_master_secret_ext ) extended_master_secret;
12041232
typeof ( *named_curve_ext )
12051233
named_curve[TLS_NUM_NAMED_CURVES ? 1 : 0];
12061234
} __attribute__ (( packed )) *extensions;
@@ -1286,6 +1314,12 @@ static int tls_client_hello ( struct tls_connection *tls,
12861314
memcpy ( session_ticket_ext->data.data, session->ticket,
12871315
sizeof ( session_ticket_ext->data.data ) );
12881316

1317+
/* Construct extended master secret extension */
1318+
extended_master_secret_ext = &extensions->extended_master_secret;
1319+
extended_master_secret_ext->type
1320+
= htons ( TLS_EXTENDED_MASTER_SECRET );
1321+
extended_master_secret_ext->len = 0;
1322+
12891323
/* Construct named curves extension, if applicable */
12901324
if ( sizeof ( extensions->named_curve ) ) {
12911325
named_curve_ext = &extensions->named_curve[0];
@@ -2091,6 +2125,9 @@ static int tls_new_server_hello ( struct tls_connection *tls,
20912125
uint8_t len;
20922126
uint8_t data[0];
20932127
} __attribute__ (( packed )) *reneg = NULL;
2128+
const struct {
2129+
uint8_t data[0];
2130+
} __attribute__ (( packed )) *ems = NULL;
20942131
uint16_t version;
20952132
size_t exts_len;
20962133
size_t ext_len;
@@ -2155,6 +2192,9 @@ static int tls_new_server_hello ( struct tls_connection *tls,
21552192
return -EINVAL_HELLO;
21562193
}
21572194
break;
2195+
case htons ( TLS_EXTENDED_MASTER_SECRET ) :
2196+
ems = ( ( void * ) ext->data );
2197+
break;
21582198
}
21592199
}
21602200
}
@@ -2188,6 +2228,9 @@ static int tls_new_server_hello ( struct tls_connection *tls,
21882228
memcpy ( &tls->server.random, &hello_a->random,
21892229
sizeof ( tls->server.random ) );
21902230

2231+
/* Handle extended master secret */
2232+
tls->extended_master_secret = ( !! ems );
2233+
21912234
/* Check session ID */
21922235
if ( hello_a->session_id_len &&
21932236
( hello_a->session_id_len == tls->session_id_len ) &&

0 commit comments

Comments
 (0)