diff options
Diffstat (limited to 'ssl/s3_lib.c')
-rw-r--r-- | ssl/s3_lib.c | 92 |
1 files changed, 76 insertions, 16 deletions
diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c index 5ea2c2d029..a75a15802a 100644 --- a/ssl/s3_lib.c +++ b/ssl/s3_lib.c @@ -4678,25 +4678,39 @@ EVP_PKEY *ssl_generate_pkey(EVP_PKEY *pm) EVP_PKEY_CTX_free(pctx); return pkey; } -#ifndef OPENSSL_NO_EC + /* Generate a private key from a group ID */ EVP_PKEY *ssl_generate_pkey_group(SSL *s, uint16_t id) { + const TLS_GROUP_INFO *ginf = tls1_group_id_lookup(id); EVP_PKEY_CTX *pctx = NULL; EVP_PKEY *pkey = NULL; - const TLS_GROUP_INFO *ginf = tls1_group_id_lookup(id); uint16_t gtype; +# ifndef OPENSSL_NO_DH + DH *dh = NULL; +# endif if (ginf == NULL) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL_GENERATE_PKEY_GROUP, ERR_R_INTERNAL_ERROR); goto err; } - gtype = ginf->flags & TLS_CURVE_TYPE; - if (gtype == TLS_CURVE_CUSTOM) - pctx = EVP_PKEY_CTX_new_id(ginf->nid, NULL); + gtype = ginf->flags & TLS_GROUP_TYPE; +# ifndef OPENSSL_NO_DH + if (gtype == TLS_GROUP_FFDHE) + pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_DH, NULL); +# ifndef OPENSSL_NO_EC else - pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL); +# endif +# endif +# ifndef OPENSSL_NO_EC + { + if (gtype == TLS_GROUP_CURVE_CUSTOM) + pctx = EVP_PKEY_CTX_new_id(ginf->nid, NULL); + else + pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL); + } +# endif if (pctx == NULL) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL_GENERATE_PKEY_GROUP, ERR_R_MALLOC_FAILURE); @@ -4707,12 +4721,40 @@ EVP_PKEY *ssl_generate_pkey_group(SSL *s, uint16_t id) ERR_R_EVP_LIB); goto err; } - if (gtype != TLS_CURVE_CUSTOM - && EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, ginf->nid) <= 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL_GENERATE_PKEY_GROUP, - ERR_R_EVP_LIB); - goto err; +# ifndef OPENSSL_NO_DH + if (gtype == TLS_GROUP_FFDHE) { + if ((pkey = EVP_PKEY_new()) == NULL + || (dh = DH_new_by_nid(ginf->nid)) == NULL + || !EVP_PKEY_assign(pkey, EVP_PKEY_DH, dh)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL_GENERATE_PKEY_GROUP, + ERR_R_EVP_LIB); + DH_free(dh); + EVP_PKEY_free(pkey); + pkey = NULL; + goto err; + } + if (EVP_PKEY_CTX_set_dh_nid(pctx, ginf->nid) <= 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL_GENERATE_PKEY_GROUP, + ERR_R_EVP_LIB); + EVP_PKEY_free(pkey); + pkey = NULL; + goto err; + } + } +# ifndef OPENSSL_NO_EC + else +# endif +# endif +# ifndef OPENSSL_NO_EC + { + if (gtype != TLS_GROUP_CURVE_CUSTOM + && EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, ginf->nid) <= 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL_GENERATE_PKEY_GROUP, + ERR_R_EVP_LIB); + goto err; + } } +# endif if (EVP_PKEY_keygen(pctx, &pkey) <= 0) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL_GENERATE_PKEY_GROUP, ERR_R_EVP_LIB); @@ -4733,11 +4775,12 @@ 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); + int pkey_ctx_id; if (ginf == NULL) goto err; - if ((ginf->flags & TLS_CURVE_TYPE) == TLS_CURVE_CUSTOM) { + if ((ginf->flags & TLS_GROUP_TYPE) == TLS_GROUP_CURVE_CUSTOM) { pkey = EVP_PKEY_new(); if (pkey != NULL && EVP_PKEY_set_type(pkey, ginf->nid)) return pkey; @@ -4745,13 +4788,28 @@ EVP_PKEY *ssl_generate_param_group(uint16_t id) return NULL; } - pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL); + pkey_ctx_id = (ginf->flags & TLS_GROUP_FFDHE) + ? EVP_PKEY_DH : EVP_PKEY_EC; + pctx = EVP_PKEY_CTX_new_id(pkey_ctx_id, 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; +# ifndef OPENSSl_NO_DH + if (ginf->flags & TLS_GROUP_FFDHE) { + if (EVP_PKEY_CTX_set_dh_nid(pctx, ginf->nid) <= 0) + goto err; + } +# ifndef OPENSSL_NO_EC + else +# endif +# endif +# ifndef OPENSSL_NO_EC + { + if (EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, ginf->nid) <= 0) + goto err; + } +# endif if (EVP_PKEY_paramgen(pctx, &pkey) <= 0) { EVP_PKEY_free(pkey); pkey = NULL; @@ -4761,7 +4819,6 @@ EVP_PKEY *ssl_generate_param_group(uint16_t id) EVP_PKEY_CTX_free(pctx); return pkey; } -#endif /* Derive secrets for ECDH/DH */ int ssl_derive(SSL *s, EVP_PKEY *privkey, EVP_PKEY *pubkey, int gensecret) @@ -4787,6 +4844,9 @@ int ssl_derive(SSL *s, EVP_PKEY *privkey, EVP_PKEY *pubkey, int gensecret) goto err; } + if (SSL_IS_TLS13(s) && EVP_PKEY_id(privkey) == EVP_PKEY_DH) + EVP_PKEY_CTX_set_dh_pad(pctx, 1); + pms = OPENSSL_malloc(pmslen); if (pms == NULL) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL_DERIVE, |