Add the ability to set PKCS#3 DH padding in providers

This also adds the ability to set arbitrary parameters on key exchange
algorithms. The ability to pad the output is one such parameter for DH.

Reviewed-by: Paul Dale <paul.dale@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/9266)
This commit is contained in:
Matt Caswell 2019-06-27 16:37:44 +01:00
parent 94b40fb77c
commit 35aca9eccb
9 changed files with 105 additions and 7 deletions

View file

@ -73,6 +73,7 @@ struct evp_keyexch_st {
OSSL_OP_keyexch_derive_fn *derive;
OSSL_OP_keyexch_freectx_fn *freectx;
OSSL_OP_keyexch_dupctx_fn *dupctx;
OSSL_OP_keyexch_set_params_fn *set_params;
} /* EVP_KEYEXCH */;

View file

@ -76,13 +76,19 @@ static void *evp_keyexch_from_dispatch(const OSSL_DISPATCH *fns,
break;
exchange->dupctx = OSSL_get_OP_keyexch_dupctx(fns);
break;
case OSSL_FUNC_KEYEXCH_SET_PARAMS:
if (exchange->set_params != NULL)
break;
exchange->set_params = OSSL_get_OP_keyexch_set_params(fns);
break;
}
}
if (fncnt != 4) {
/*
* In order to be a consistent set of functions we must have at least
* a complete set of "exchange" functions: init, derive, newctx,
* and freectx. The dupctx and set_peer functions are optional.
* and freectx. The dupctx, set_peer and set_params functions are
* optional.
*/
EVP_KEYEXCH_free(exchange);
EVPerr(EVP_F_EVP_KEYEXCH_FROM_DISPATCH,

View file

@ -9,10 +9,12 @@
#include <stdio.h>
#include <stdlib.h>
#include "internal/cryptlib.h"
#include <openssl/engine.h>
#include <openssl/evp.h>
#include <openssl/x509v3.h>
#include <openssl/core_names.h>
#include <openssl/dh.h>
#include "internal/cryptlib.h"
#include "internal/asn1_int.h"
#include "internal/evp_int.h"
#include "internal/numbers.h"
@ -384,12 +386,52 @@ void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx)
OPENSSL_free(ctx);
}
int EVP_PKEY_CTX_set_params(EVP_PKEY_CTX *ctx, OSSL_PARAM *params)
{
if (ctx->exchprovctx != NULL && ctx->exchange != NULL)
return ctx->exchange->set_params(ctx->exchprovctx, params);
return 0;
}
int EVP_PKEY_CTX_set_dh_pad(EVP_PKEY_CTX *ctx, int pad)
{
OSSL_PARAM dh_pad_params[2];
/* TODO(3.0): Remove this eventually when no more legacy */
if (ctx->exchprovctx == NULL)
return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_DERIVE,
EVP_PKEY_CTRL_DH_PAD, pad, NULL);
dh_pad_params[0] = OSSL_PARAM_construct_int(OSSL_EXCHANGE_PARAM_PAD, &pad);
dh_pad_params[1] = OSSL_PARAM_construct_end();
return EVP_PKEY_CTX_set_params(ctx, dh_pad_params);
}
static int legacy_ctrl_to_param(EVP_PKEY_CTX *ctx, int keytype, int optype,
int cmd, int p1, void *p2)
{
switch (cmd) {
case EVP_PKEY_CTRL_DH_PAD:
return EVP_PKEY_CTX_set_dh_pad(ctx, p1);
}
return 0;
}
int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype,
int cmd, int p1, void *p2)
{
int ret;
if (!ctx || !ctx->pmeth || !ctx->pmeth->ctrl) {
if (ctx == NULL) {
EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_COMMAND_NOT_SUPPORTED);
return -2;
}
if (ctx->exchprovctx != NULL)
return legacy_ctrl_to_param(ctx, keytype, optype, cmd, p1, p2);
if (ctx->pmeth == NULL || ctx->pmeth->ctrl == NULL) {
EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_COMMAND_NOT_SUPPORTED);
return -2;
}
@ -425,9 +467,29 @@ int EVP_PKEY_CTX_ctrl_uint64(EVP_PKEY_CTX *ctx, int keytype, int optype,
return EVP_PKEY_CTX_ctrl(ctx, keytype, optype, cmd, 0, &value);
}
static int legacy_ctrl_str_to_param(EVP_PKEY_CTX *ctx, const char *name,
const char *value)
{
if (strcmp(name, "dh_pad") == 0) {
int pad;
pad = atoi(value);
return EVP_PKEY_CTX_set_dh_pad(ctx, pad);
}
return 0;
}
int EVP_PKEY_CTX_ctrl_str(EVP_PKEY_CTX *ctx,
const char *name, const char *value)
{
if (ctx == NULL) {
EVPerr(EVP_F_EVP_PKEY_CTX_CTRL_STR, EVP_R_COMMAND_NOT_SUPPORTED);
return -2;
}
if (ctx->exchprovctx != NULL)
return legacy_ctrl_str_to_param(ctx, name, value);
if (!ctx || !ctx->pmeth || !ctx->pmeth->ctrl_str) {
EVPerr(EVP_F_EVP_PKEY_CTX_CTRL_STR, EVP_R_COMMAND_NOT_SUPPORTED);
return -2;

View file

@ -65,6 +65,10 @@ extern "C" {
#define OSSL_PKEY_PARAM_DH_PUB_KEY "dh-pub"
#define OSSL_PKEY_PARAM_DH_PRIV_KEY "dh-priv"
/* Key Exchange parameters */
#define OSSL_EXCHANGE_PARAM_PAD "exchange-pad"
# ifdef __cplusplus
}
# endif

View file

@ -239,6 +239,7 @@ OSSL_CORE_MAKE_FUNC(int, OP_cipher_ctx_set_params, (void *cctx,
# define OSSL_FUNC_KEYEXCH_SET_PEER 4
# define OSSL_FUNC_KEYEXCH_FREECTX 5
# define OSSL_FUNC_KEYEXCH_DUPCTX 6
# define OSSL_FUNC_KEYEXCH_SET_PARAMS 7
OSSL_CORE_MAKE_FUNC(void *, OP_keyexch_newctx, (void *provctx))
OSSL_CORE_MAKE_FUNC(int, OP_keyexch_init, (void *ctx,
@ -249,6 +250,8 @@ OSSL_CORE_MAKE_FUNC(int, OP_keyexch_set_peer, (void *ctx,
OSSL_PARAM params[]))
OSSL_CORE_MAKE_FUNC(void, OP_keyexch_freectx, (void *ctx))
OSSL_CORE_MAKE_FUNC(void *, OP_keyexch_dupctx, (void *ctx))
OSSL_CORE_MAKE_FUNC(int, OP_keyexch_set_params, (void *ctx,
OSSL_PARAM params[]))
# ifdef __cplusplus
}

View file

@ -253,9 +253,7 @@ int DH_meth_set_generate_params(DH_METHOD *dhm,
EVP_PKEY_OP_PARAMGEN | EVP_PKEY_OP_KEYGEN, \
EVP_PKEY_CTRL_DH_NID, nid, NULL)
# define EVP_PKEY_CTX_set_dh_pad(ctx, pad) \
EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_DERIVE, \
EVP_PKEY_CTRL_DH_PAD, pad, NULL)
int EVP_PKEY_CTX_set_dh_pad(EVP_PKEY_CTX *ctx, int pad);
# define EVP_PKEY_CTX_set_dh_kdf_type(ctx, kdf) \
EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \

View file

@ -1416,6 +1416,7 @@ EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e);
EVP_PKEY_CTX *EVP_PKEY_CTX_dup(const EVP_PKEY_CTX *ctx);
void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx);
int EVP_PKEY_CTX_set_params(EVP_PKEY_CTX *ctx, OSSL_PARAM *params);
int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype,
int cmd, int p1, void *p2);
int EVP_PKEY_CTX_ctrl_str(EVP_PKEY_CTX *ctx, const char *type,

View file

@ -25,6 +25,7 @@ static OSSL_OP_keyexch_dupctx_fn dh_dupctx;
typedef struct {
DH *dh;
DH *dhpeer;
int pad;
} PROV_DH_CTX;
static void *dh_newctx(void *provctx)
@ -122,7 +123,8 @@ static int dh_derive(void *vpdhctx, unsigned char *key, size_t *keylen,
return 0;
DH_get0_key(pdhctx->dhpeer, &pub_key, NULL);
ret = DH_compute_key(key, pub_key, pdhctx->dh);
ret = (pdhctx->pad) ? DH_compute_key_padded(key, pub_key, pdhctx->dh)
: DH_compute_key(key, pub_key, pdhctx->dh);
if (ret <= 0)
return 0;
@ -162,6 +164,24 @@ static void *dh_dupctx(void *vpdhctx)
return dstctx;
}
static int dh_set_params(void *vpdhctx, OSSL_PARAM params[])
{
PROV_DH_CTX *pdhctx = (PROV_DH_CTX *)vpdhctx;
const OSSL_PARAM *p;
int pad;
if (pdhctx == NULL || params == NULL)
return 0;
p = OSSL_PARAM_locate(params, OSSL_EXCHANGE_PARAM_PAD);
if (p == NULL || !OSSL_PARAM_get_int(p, &pad))
return 0;
pdhctx->pad = pad;
return 1;
}
const OSSL_DISPATCH dh_functions[] = {
{ OSSL_FUNC_KEYEXCH_NEWCTX, (void (*)(void))dh_newctx },
{ OSSL_FUNC_KEYEXCH_INIT, (void (*)(void))dh_init },
@ -169,5 +189,6 @@ const OSSL_DISPATCH dh_functions[] = {
{ OSSL_FUNC_KEYEXCH_SET_PEER, (void (*)(void))dh_set_peer },
{ OSSL_FUNC_KEYEXCH_FREECTX, (void (*)(void))dh_freectx },
{ OSSL_FUNC_KEYEXCH_DUPCTX, (void (*)(void))dh_dupctx },
{ OSSL_FUNC_KEYEXCH_SET_PARAMS, (void (*)(void))dh_set_params },
{ 0, NULL }
};

View file

@ -4683,3 +4683,5 @@ EVP_PKEY_derive_init_ex 4788 3_0_0 EXIST::FUNCTION:
EVP_KEYEXCH_free 4789 3_0_0 EXIST::FUNCTION:
EVP_KEYEXCH_up_ref 4790 3_0_0 EXIST::FUNCTION:
EVP_KEYEXCH_fetch 4791 3_0_0 EXIST::FUNCTION:
EVP_PKEY_CTX_set_dh_pad 4792 3_0_0 EXIST::FUNCTION:DH
EVP_PKEY_CTX_set_params 4793 3_0_0 EXIST::FUNCTION: