[tls] Use generic key exchange algorithm abstraction for ECDHE

Remove any knowledge of elliptic curve point formats from the TLS
layer and use the generic key exchange algorithm abstraction instead.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
Michael Brown
2026-06-06 16:26:10 +01:00
parent 3bd8516e9b
commit 3faae34685
5 changed files with 29 additions and 48 deletions
+1 -3
View File
@@ -41,8 +41,6 @@ struct asn1_algorithm prime256v1_algorithm __asn1_algorithm = {
/** P-256 named curve */
struct tls_named_curve tls_secp256r1_named_curve __tls_named_curve ( 01 ) = {
.curve = &p256_curve,
.exchange = &p256_algorithm,
.code = htons ( TLS_NAMED_CURVE_SECP256R1 ),
.format = TLS_POINT_FORMAT_UNCOMPRESSED,
.pre_master_secret_len = P256_LEN,
};
+1 -3
View File
@@ -41,8 +41,6 @@ struct asn1_algorithm secp384r1_algorithm __asn1_algorithm = {
/** P-384 named curve */
struct tls_named_curve tls_secp384r1_named_curve __tls_named_curve ( 01 ) = {
.curve = &p384_curve,
.exchange = &p384_algorithm,
.code = htons ( TLS_NAMED_CURVE_SECP384R1 ),
.format = TLS_POINT_FORMAT_UNCOMPRESSED,
.pre_master_secret_len = P384_LEN,
};
+1 -2
View File
@@ -41,7 +41,6 @@ struct asn1_algorithm oid_x25519_algorithm __asn1_algorithm = {
/** X25519 named curve */
struct tls_named_curve tls_x25519_named_curve __tls_named_curve ( 01 ) = {
.curve = &x25519_curve,
.exchange = &x25519_algorithm,
.code = htons ( TLS_NAMED_CURVE_X25519 ),
.pre_master_secret_len = sizeof ( struct x25519_value ),
};
+2 -6
View File
@@ -244,14 +244,10 @@ struct tls_cipher_suite {
/** A TLS named curve */
struct tls_named_curve {
/** Elliptic curve */
struct elliptic_curve *curve;
/** Key exchange algorithm */
struct exchange_algorithm *exchange;
/** Numeric code (in network-endian order) */
uint16_t code;
/** Curve point format byte (if any) */
uint8_t format;
/** Pre-master secret length */
uint8_t pre_master_secret_len;
};
/** TLS named curve table */
+24 -34
View File
@@ -1634,6 +1634,7 @@ struct tls_key_exchange_algorithm tls_dhe_exchange_algorithm = {
*/
static int tls_send_client_key_exchange_ecdhe ( struct tls_connection *tls ) {
struct tls_named_curve *curve;
struct exchange_algorithm *exchange;
const struct {
uint8_t curve_type;
uint16_t named_curve;
@@ -1641,9 +1642,9 @@ static int tls_send_client_key_exchange_ecdhe ( struct tls_connection *tls ) {
uint8_t public[0];
} __attribute__ (( packed )) *ecdh;
size_t param_len;
size_t pointsize;
size_t keysize;
size_t offset;
size_t privsize;
size_t pubsize;
size_t sharedsize;
int rc;
/* Parse ServerKeyExchange record */
@@ -1679,24 +1680,15 @@ static int tls_send_client_key_exchange_ecdhe ( struct tls_connection *tls ) {
tls->server.exchange_len );
return -ENOTSUP_CURVE;
}
DBGC ( tls, "TLS %p using named curve %s\n", tls, curve->curve->name );
pointsize = curve->curve->pointsize;
keysize = curve->curve->keysize;
offset = ( curve->format ? 1 : 0 );
exchange = curve->exchange;
privsize = exchange->privsize;
pubsize = exchange->pubsize;
sharedsize = exchange->sharedsize;
DBGC ( tls, "TLS %p using named curve %s\n", tls, exchange->name );
/* Check key length */
if ( ecdh->public_len != ( offset + pointsize ) ) {
DBGC ( tls, "TLS %p invalid %s key\n",
tls, curve->curve->name );
DBGC_HDA ( tls, 0, tls->server.exchange,
tls->server.exchange_len );
return -EINVAL_KEY_EXCHANGE;
}
/* Check curve point format byte (if present) */
if ( curve->format && ( ecdh->public[0] != curve->format ) ) {
DBGC ( tls, "TLS %p invalid %s curve point format\n",
tls, curve->curve->name );
if ( ecdh->public_len != pubsize ) {
DBGC ( tls, "TLS %p invalid %s key\n", tls, exchange->name );
DBGC_HDA ( tls, 0, tls->server.exchange,
tls->server.exchange_len );
return -EINVAL_KEY_EXCHANGE;
@@ -1704,12 +1696,12 @@ static int tls_send_client_key_exchange_ecdhe ( struct tls_connection *tls ) {
/* Construct pre-master secret and ClientKeyExchange record */
{
uint8_t private[keysize];
uint8_t pre_master_secret[pointsize];
uint8_t private[privsize];
uint8_t pre_master_secret[sharedsize];
struct {
uint32_t type_length;
uint8_t public_len;
uint8_t public[ecdh->public_len];
uint8_t public[pubsize];
} __attribute__ (( packed )) key_xchg;
/* Generate ephemeral private key */
@@ -1718,23 +1710,13 @@ static int tls_send_client_key_exchange_ecdhe ( struct tls_connection *tls ) {
return rc;
}
/* Exchange keys */
if ( ( rc = ecdhe_key ( curve->curve, ( ecdh->public + offset ),
private, ( key_xchg.public + offset ),
pre_master_secret ) ) != 0 ) {
DBGC ( tls, "TLS %p could not exchange ECDHE key: %s\n",
tls, strerror ( rc ) );
return rc;
}
/* Generate Client Key Exchange record */
key_xchg.type_length =
( cpu_to_le32 ( TLS_CLIENT_KEY_EXCHANGE ) |
htonl ( sizeof ( key_xchg ) -
sizeof ( key_xchg.type_length ) ) );
key_xchg.public_len = sizeof ( key_xchg.public );
if ( curve->format )
key_xchg.public[0] = curve->format;
exchange_public ( exchange, private, key_xchg.public );
/* Transmit Client Key Exchange record */
if ( ( rc = tls_send_handshake ( tls, &key_xchg,
@@ -1742,9 +1724,17 @@ static int tls_send_client_key_exchange_ecdhe ( struct tls_connection *tls ) {
return rc;
}
/* Generate pre-master secret */
if ( ( rc = exchange_shared ( exchange, private, ecdh->public,
pre_master_secret ) ) != 0 ) {
DBGC ( tls, "TLS %p could not exchange keys: %s\n",
tls, strerror ( rc ) );
return rc;
}
/* Generate master secret */
tls_generate_master_secret ( tls, pre_master_secret,
curve->pre_master_secret_len );
sizeof ( pre_master_secret ) );
}
return 0;