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:
parent
94b40fb77c
commit
35aca9eccb
9 changed files with 105 additions and 7 deletions
|
@ -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 */;
|
||||
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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, \
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 }
|
||||
};
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Reference in a new issue