From 6b69ab68b47d0933f8b4a1d7ed8460274a736a5f Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 26 Apr 2021 13:46:36 +0200 Subject: [PATCH] tls: make x25519 key generation code more similar to P256 function old new delta curve_x25519_compute_pubkey_and_premaster - 74 +74 tls_handshake 2146 2072 -74 ------------------------------------------------------------------------------ (add/remove: 1/0 grow/shrink: 0/1 up/down: 74/-74) Total: 0 bytes Signed-off-by: Denys Vlasenko --- networking/tls.c | 61 +++++++++++++++++++-------------------------- networking/tls.h | 5 +++- networking/tls_fe.c | 23 ++++++++++++++++- networking/tls_fe.h | 6 ----- 4 files changed, 51 insertions(+), 44 deletions(-) delete mode 100644 networking/tls_fe.h diff --git a/networking/tls.c b/networking/tls.c index cacd2e9ff..5566d7911 100644 --- a/networking/tls.c +++ b/networking/tls.c @@ -1534,7 +1534,7 @@ static void send_client_hello_and_alloc_hsd(tls_state_t *tls, const char *sni) 0x00,0x0a, //extension_type: "supported_groups" 0x00,0x06, //ext len 0x00,0x04, //list len - 0x00,0x17, //curve_secp256r1 + 0x00,0x17, //curve_secp256r1 (aka P256) //0x00,0x18, //curve_secp384r1 //0x00,0x19, //curve_secp521r1 0x00,0x1d, //curve_x25519 (RFC 7748) @@ -1890,7 +1890,7 @@ static void process_server_key(tls_state_t *tls, int len) tls->flags |= GOT_EC_CURVE_X25519; memcpy(tls->hsd->ecc_pub_key32, keybuf, 32); break; - case _0x03001741: //curve_secp256r1 + case _0x03001741: //curve_secp256r1 (aka P256) /* P256 point can be transmitted odd- or even-compressed * (first byte is 3 or 2) or uncompressed (4). */ @@ -1967,46 +1967,35 @@ static void send_client_key_exchange(tls_state_t *tls) record->key[1] = len & 0xff; len += 2; premaster_size = RSA_PREMASTER_SIZE; - } else /* ECDHE */ - if (tls->flags & GOT_EC_CURVE_X25519) { - /* ECDHE, curve x25519 */ - static const uint8_t basepoint9[CURVE25519_KEYSIZE] ALIGN8 = {9}; - uint8_t privkey[CURVE25519_KEYSIZE]; //[32] - - if (!(tls->flags & GOT_EC_KEY)) - bb_simple_error_msg_and_die("server did not provide EC key"); - - /* Generate random private key, see RFC 7748 */ - tls_get_random(privkey, sizeof(privkey)); - privkey[0] &= 0xf8; - privkey[CURVE25519_KEYSIZE-1] = ((privkey[CURVE25519_KEYSIZE-1] & 0x7f) | 0x40); - - /* Compute public key */ - curve25519(record->key + 1, privkey, basepoint9); - - /* Compute premaster using peer's public key */ - dbg("computing x25519_premaster\n"); - curve25519(premaster, privkey, tls->hsd->ecc_pub_key32); - - len = CURVE25519_KEYSIZE; - record->key[0] = len; - len++; - premaster_size = CURVE25519_KEYSIZE; } else { - /* ECDHE, curve P256 */ + /* ECDHE */ if (!(tls->flags & GOT_EC_KEY)) bb_simple_error_msg_and_die("server did not provide EC key"); - dbg("computing P256_premaster\n"); - curve_P256_compute_pubkey_and_premaster( - record->key + 2, premaster, - /*point:*/ tls->hsd->ecc_pub_key32 - ); - premaster_size = P256_KEYSIZE; - len = 1 + P256_KEYSIZE * 2; + if (tls->flags & GOT_EC_CURVE_X25519) { + /* ECDHE, curve x25519 */ + dbg("computing x25519_premaster\n"); + curve_x25519_compute_pubkey_and_premaster( + record->key + 1, premaster, + /*point:*/ tls->hsd->ecc_pub_key32 + ); + len = CURVE25519_KEYSIZE; + //record->key[0] = len; + //len++; + //premaster_size = CURVE25519_KEYSIZE; + } else { + /* ECDHE, curve P256 */ + dbg("computing P256_premaster\n"); + curve_P256_compute_pubkey_and_premaster( + record->key + 2, premaster, + /*point:*/ tls->hsd->ecc_pub_key32 + ); + record->key[1] = 4; /* "uncompressed point" */ + len = 1 + P256_KEYSIZE * 2; + } record->key[0] = len; - record->key[1] = 4; len++; + premaster_size = P256_KEYSIZE; // = CURVE25519_KEYSIZE = 32 } record->type = HANDSHAKE_CLIENT_KEY_EXCHANGE; diff --git a/networking/tls.h b/networking/tls.h index e1afb7ea8..154e9b2fb 100644 --- a/networking/tls.h +++ b/networking/tls.h @@ -105,12 +105,15 @@ void xorbuf_aligned_AES_BLOCK_SIZE(void* buf, const void* mask) FAST_FUNC; #include "tls_aes.h" #include "tls_aesgcm.h" #include "tls_rsa.h" -#include "tls_fe.h" #define EC_CURVE_KEYSIZE 32 #define P256_KEYSIZE 32 #define CURVE25519_KEYSIZE 32 +void curve_x25519_compute_pubkey_and_premaster( + uint8_t *pubkey, uint8_t *premaster, + const uint8_t *peerkey32) FAST_FUNC; + void curve_P256_compute_pubkey_and_premaster( uint8_t *pubkey, uint8_t *premaster, const uint8_t *peerkey32) FAST_FUNC; diff --git a/networking/tls_fe.c b/networking/tls_fe.c index f810e112a..3b3578c0d 100644 --- a/networking/tls_fe.c +++ b/networking/tls_fe.c @@ -544,7 +544,7 @@ static void xc_double(byte *x3, byte *z3, fe_mul_c(z3, x1sq, 4); } -void FAST_FUNC curve25519(byte *result, const byte *e, const byte *q) +static void curve25519(byte *result, const byte *e, const byte *q) { int i; @@ -599,3 +599,24 @@ void FAST_FUNC curve25519(byte *result, const byte *e, const byte *q) fe_mul__distinct(result, zm1, xm); fe_normalize(result); } + +/* interface to bbox's TLS code: */ + +void FAST_FUNC curve_x25519_compute_pubkey_and_premaster( + uint8_t *pubkey, uint8_t *premaster, + const uint8_t *peerkey32) +{ + static const uint8_t basepoint9[CURVE25519_KEYSIZE] ALIGN8 = {9}; + uint8_t privkey[CURVE25519_KEYSIZE]; //[32] + + /* Generate random private key, see RFC 7748 */ + tls_get_random(privkey, sizeof(privkey)); + privkey[0] &= 0xf8; + privkey[CURVE25519_KEYSIZE-1] = ((privkey[CURVE25519_KEYSIZE-1] & 0x7f) | 0x40); + + /* Compute public key */ + curve25519(pubkey, privkey, basepoint9); + + /* Compute premaster using peer's public key */ + curve25519(premaster, privkey, peerkey32); +} diff --git a/networking/tls_fe.h b/networking/tls_fe.h deleted file mode 100644 index 2859c9d2d..000000000 --- a/networking/tls_fe.h +++ /dev/null @@ -1,6 +0,0 @@ -/* - * Copyright (C) 2018 Denys Vlasenko - * - * Licensed under GPLv2, see file LICENSE in this source tree. - */ -void curve25519(uint8_t *result, const uint8_t *e, const uint8_t *q) FAST_FUNC;