aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/crypto/mishmash/oid_x25519.c1
-rw-r--r--src/crypto/x25519.c1
-rw-r--r--src/include/ipxe/crypto.h4
-rw-r--r--src/include/ipxe/tls.h7
-rw-r--r--src/net/tls.c38
5 files changed, 40 insertions, 11 deletions
diff --git a/src/crypto/mishmash/oid_x25519.c b/src/crypto/mishmash/oid_x25519.c
index 2f8aa065b..30b7905ea 100644
--- a/src/crypto/mishmash/oid_x25519.c
+++ b/src/crypto/mishmash/oid_x25519.c
@@ -42,4 +42,5 @@ struct asn1_algorithm x25519_algorithm __asn1_algorithm = {
struct tls_named_curve tls_x25519_named_curve __tls_named_curve ( 01 ) = {
.curve = &x25519_curve,
.code = htons ( TLS_NAMED_CURVE_X25519 ),
+ .pre_master_secret_len = sizeof ( struct x25519_value ),
};
diff --git a/src/crypto/x25519.c b/src/crypto/x25519.c
index ab5d2e8b0..995cfa352 100644
--- a/src/crypto/x25519.c
+++ b/src/crypto/x25519.c
@@ -839,6 +839,7 @@ static int x25519_curve_multiply ( const void *base, const void *scalar,
/** X25519 elliptic curve */
struct elliptic_curve x25519_curve = {
.name = "x25519",
+ .pointsize = sizeof ( struct x25519_value ),
.keysize = sizeof ( struct x25519_value ),
.multiply = x25519_curve_multiply,
};
diff --git a/src/include/ipxe/crypto.h b/src/include/ipxe/crypto.h
index dcc73f3ef..4bd543ae2 100644
--- a/src/include/ipxe/crypto.h
+++ b/src/include/ipxe/crypto.h
@@ -184,7 +184,9 @@ struct pubkey_algorithm {
struct elliptic_curve {
/** Curve name */
const char *name;
- /** Key size */
+ /** Point (and public key) size */
+ size_t pointsize;
+ /** Scalar (and private key) size */
size_t keysize;
/** Multiply scalar by curve point
*
diff --git a/src/include/ipxe/tls.h b/src/include/ipxe/tls.h
index 08d58689e..bf9807230 100644
--- a/src/include/ipxe/tls.h
+++ b/src/include/ipxe/tls.h
@@ -218,12 +218,19 @@ struct tls_cipher_suite {
/** TLS named curved type */
#define TLS_NAMED_CURVE_TYPE 3
+/** TLS uncompressed curve point format */
+#define TLS_POINT_FORMAT_UNCOMPRESSED 4
+
/** A TLS named curve */
struct tls_named_curve {
/** Elliptic curve */
struct elliptic_curve *curve;
/** 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 */
diff --git a/src/net/tls.c b/src/net/tls.c
index 286d2cc9f..a94e71c8a 100644
--- a/src/net/tls.c
+++ b/src/net/tls.c
@@ -1671,6 +1671,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;
int rc;
/* Parse ServerKeyExchange record */
@@ -1706,9 +1709,13 @@ 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 );
/* Check key length */
- if ( ecdh->public_len != curve->curve->keysize ) {
+ 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,
@@ -1716,15 +1723,23 @@ static int tls_send_client_key_exchange_ecdhe ( struct tls_connection *tls ) {
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 );
+ DBGC_HDA ( tls, 0, tls->server.exchange,
+ tls->server.exchange_len );
+ return -EINVAL_KEY_EXCHANGE;
+ }
+
/* Construct pre-master secret and ClientKeyExchange record */
{
- size_t len = curve->curve->keysize;
- uint8_t private[len];
- uint8_t pre_master_secret[len];
+ uint8_t private[keysize];
+ uint8_t pre_master_secret[pointsize];
struct {
uint32_t type_length;
uint8_t public_len;
- uint8_t public[len];
+ uint8_t public[ecdh->public_len];
} __attribute__ (( packed )) key_xchg;
/* Generate ephemeral private key */
@@ -1733,9 +1748,9 @@ static int tls_send_client_key_exchange_ecdhe ( struct tls_connection *tls ) {
return rc;
}
- /* Calculate pre-master secret */
- if ( ( rc = ecdhe_key ( curve->curve, ecdh->public,
- private, key_xchg.public,
+ /* 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 ) );
@@ -1743,14 +1758,17 @@ static int tls_send_client_key_exchange_ecdhe ( struct tls_connection *tls ) {
}
/* Generate master secret */
- tls_generate_master_secret ( tls, pre_master_secret, len );
+ tls_generate_master_secret ( tls, pre_master_secret,
+ curve->pre_master_secret_len );
/* 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 = len;
+ key_xchg.public_len = sizeof ( key_xchg.public );
+ if ( curve->format )
+ key_xchg.public[0] = curve->format;
/* Transmit Client Key Exchange record */
if ( ( rc = tls_send_handshake ( tls, &key_xchg,