Commit 612f9d22 authored by Dr. Stephen Henson's avatar Dr. Stephen Henson
Browse files

New function ssl_generate_param_group



Setup EVP_PKEY structure from a group ID in ssl_generate_param_group,
replace duplicate code with this function.

Reviewed-by: default avatarRich Salz <rsalz@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/=4412)
parent 43b95d73
Loading
Loading
Loading
Loading
+37 −0
Original line number Diff line number Diff line
@@ -4621,6 +4621,43 @@ EVP_PKEY *ssl_generate_pkey_group(uint16_t id)
    EVP_PKEY_CTX_free(pctx);
    return pkey;
}

/*
 * Generate parameters from a group ID
 */
EVP_PKEY *ssl_generate_param_group(uint16_t id)
{
    EVP_PKEY_CTX *pctx = NULL;
    EVP_PKEY *pkey = NULL;
    const TLS_GROUP_INFO *ginf = tls1_group_id_lookup(id);

    if (ginf == NULL)
        goto err;

    if ((ginf->flags & TLS_CURVE_TYPE) == TLS_CURVE_CUSTOM) {
        pkey = EVP_PKEY_new();
        if (pkey != NULL && EVP_PKEY_set_type(pkey, ginf->nid))
            return pkey;
        EVP_PKEY_free(pkey);
        return NULL;
    }

    pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL);
    if (pctx == NULL)
        goto err;
    if (EVP_PKEY_paramgen_init(pctx) <= 0)
        goto err;
    if (EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, ginf->nid) <= 0)
        goto err;
    if (EVP_PKEY_paramgen(pctx, &pkey) <= 0) {
        EVP_PKEY_free(pkey);
        pkey = NULL;
    }

 err:
    EVP_PKEY_CTX_free(pctx);
    return pkey;
}
#endif

/* Derive secrets for ECDH/DH */
+1 −0
Original line number Diff line number Diff line
@@ -2351,6 +2351,7 @@ void tls1_get_formatlist(SSL *s, const unsigned char **pformats,
                         size_t *num_formats);
__owur int tls1_check_ec_tmp_key(SSL *s, unsigned long id);
__owur EVP_PKEY *ssl_generate_pkey_group(uint16_t id);
__owur EVP_PKEY *ssl_generate_param_group(uint16_t id);
#  endif                        /* OPENSSL_NO_EC */

__owur int tls_curve_allowed(SSL *s, uint16_t curve, int op);
+1 −32
Original line number Diff line number Diff line
@@ -502,7 +502,6 @@ int tls_parse_ctos_key_share(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
    const uint16_t *clntcurves, *srvrcurves;
    size_t clnt_num_curves, srvr_num_curves;
    int found = 0;
    const TLS_GROUP_INFO *ginf;

    if (s->hit && (s->ext.psk_kex_mode & TLSEXT_KEX_MODE_FLAG_KE_DHE) == 0)
        return 1;
@@ -575,43 +574,13 @@ int tls_parse_ctos_key_share(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
            continue;
        }

        ginf = tls1_group_id_lookup(group_id);

        if (ginf == NULL) {
        if ((s->s3->peer_tmp = ssl_generate_param_group(group_id)) == NULL) {
            *al = SSL_AD_INTERNAL_ERROR;
            SSLerr(SSL_F_TLS_PARSE_CTOS_KEY_SHARE,
                   SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS);
            return 0;
        }

        if ((ginf->flags & TLS_CURVE_TYPE) == TLS_CURVE_CUSTOM) {
            /* Can happen for some curves, e.g. X25519 */
            EVP_PKEY *key = EVP_PKEY_new();

            if (key == NULL || !EVP_PKEY_set_type(key, ginf->nid)) {
                *al = SSL_AD_INTERNAL_ERROR;
                SSLerr(SSL_F_TLS_PARSE_CTOS_KEY_SHARE, ERR_R_EVP_LIB);
                EVP_PKEY_free(key);
                return 0;
            }
            s->s3->peer_tmp = key;
        } else {
            /* Set up EVP_PKEY with named curve as parameters */
            EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL);

            if (pctx == NULL
                    || EVP_PKEY_paramgen_init(pctx) <= 0
                    || EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx,
                                                              ginf->nid) <= 0
                    || EVP_PKEY_paramgen(pctx, &s->s3->peer_tmp) <= 0) {
                *al = SSL_AD_INTERNAL_ERROR;
                SSLerr(SSL_F_TLS_PARSE_CTOS_KEY_SHARE, ERR_R_EVP_LIB);
                EVP_PKEY_CTX_free(pctx);
                return 0;
            }
            EVP_PKEY_CTX_free(pctx);
            pctx = NULL;
        }
        s->s3->group_id = group_id;

        if (!EVP_PKEY_set1_tls_encodedpoint(s->s3->peer_tmp,
+1 −31
Original line number Diff line number Diff line
@@ -2041,8 +2041,6 @@ static int tls_process_ske_ecdhe(SSL *s, PACKET *pkt, EVP_PKEY **pkey, int *al)
#ifndef OPENSSL_NO_EC
    PACKET encoded_pt;
    const unsigned char *ecparams;
    const TLS_GROUP_INFO *ginf;
    EVP_PKEY_CTX *pctx = NULL;

    /*
     * Extract elliptic curve parameters and the server's ephemeral ECDH
@@ -2064,41 +2062,13 @@ static int tls_process_ske_ecdhe(SSL *s, PACKET *pkt, EVP_PKEY **pkey, int *al)
        return 0;
    }

    ginf = tls1_group_id_lookup(ecparams[2]);

    if (ginf == NULL) {
    if ((s->s3->peer_tmp = ssl_generate_param_group(ecparams[2])) == NULL) {
        *al = SSL_AD_INTERNAL_ERROR;
        SSLerr(SSL_F_TLS_PROCESS_SKE_ECDHE,
               SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS);
        return 0;
    }

    if ((ginf->flags & TLS_CURVE_TYPE) == TLS_CURVE_CUSTOM) {
        EVP_PKEY *key = EVP_PKEY_new();

        if (key == NULL || !EVP_PKEY_set_type(key, ginf->nid)) {
            *al = SSL_AD_INTERNAL_ERROR;
            SSLerr(SSL_F_TLS_PROCESS_SKE_ECDHE, ERR_R_EVP_LIB);
            EVP_PKEY_free(key);
            return 0;
        }
        s->s3->peer_tmp = key;
    } else {
        /* Set up EVP_PKEY with named curve as parameters */
        pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL);
        if (pctx == NULL
            || EVP_PKEY_paramgen_init(pctx) <= 0
            || EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, ginf->nid) <= 0
            || EVP_PKEY_paramgen(pctx, &s->s3->peer_tmp) <= 0) {
            *al = SSL_AD_INTERNAL_ERROR;
            SSLerr(SSL_F_TLS_PROCESS_SKE_ECDHE, ERR_R_EVP_LIB);
            EVP_PKEY_CTX_free(pctx);
            return 0;
        }
        EVP_PKEY_CTX_free(pctx);
        pctx = NULL;
    }

    if (!PACKET_get_length_prefixed_1(pkt, &encoded_pt)) {
        *al = SSL_AD_DECODE_ERROR;
        SSLerr(SSL_F_TLS_PROCESS_SKE_ECDHE, SSL_R_LENGTH_MISMATCH);