Revise EVP_PKEY param handling

We add new functions for getting parameters and discovering the gettable
and settable parameters. We also make EVP_PKEY_CTX_get_signature_md() a
function and implement it in terms of the new functions.

This enables applications to discover the set of parameters that are
supported for a given algorithm implementation.

Reviewed-by: Richard Levitte <levitte@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/9753)
This commit is contained in:
Matt Caswell 2019-09-04 12:46:02 +01:00
parent 21fb706722
commit 9c45222ddc
13 changed files with 464 additions and 99 deletions

View File

@ -110,7 +110,8 @@ 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;
OSSL_OP_keyexch_set_ctx_params_fn *set_ctx_params;
OSSL_OP_keyexch_settable_ctx_params_fn *settable_ctx_params;
} /* EVP_KEYEXCH */;
struct evp_signature_st {
@ -130,7 +131,10 @@ struct evp_signature_st {
OSSL_OP_signature_verify_recover_fn *verify_recover;
OSSL_OP_signature_freectx_fn *freectx;
OSSL_OP_signature_dupctx_fn *dupctx;
OSSL_OP_signature_set_params_fn *set_params;
OSSL_OP_signature_get_ctx_params_fn *get_ctx_params;
OSSL_OP_signature_gettable_ctx_params_fn *gettable_ctx_params;
OSSL_OP_signature_set_ctx_params_fn *set_ctx_params;
OSSL_OP_signature_settable_ctx_params_fn *settable_ctx_params;
} /* EVP_SIGNATURE */;
int PKCS5_v2_PBKDF2_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass,

View File

@ -50,7 +50,7 @@ static void *evp_keyexch_from_dispatch(const char *name,
EVP_KEYMGMT *keymgmt = EVP_KEYMGMT_fetch(keymgmt_data->ctx, name,
keymgmt_data->properties);
EVP_KEYEXCH *exchange = NULL;
int fncnt = 0;
int fncnt = 0, paramfncnt = 0;
if (keymgmt == NULL || EVP_KEYMGMT_provider(keymgmt) != prov) {
ERR_raise(ERR_LIB_EVP, EVP_R_NO_KEYMGMT_AVAILABLE);
@ -102,19 +102,28 @@ static void *evp_keyexch_from_dispatch(const char *name,
break;
exchange->dupctx = OSSL_get_OP_keyexch_dupctx(fns);
break;
case OSSL_FUNC_KEYEXCH_SET_PARAMS:
if (exchange->set_params != NULL)
case OSSL_FUNC_KEYEXCH_SET_CTX_PARAMS:
if (exchange->set_ctx_params != NULL)
break;
exchange->set_params = OSSL_get_OP_keyexch_set_params(fns);
exchange->set_ctx_params = OSSL_get_OP_keyexch_set_ctx_params(fns);
paramfncnt++;
break;
case OSSL_FUNC_KEYEXCH_SETTABLE_CTX_PARAMS:
if (exchange->settable_ctx_params != NULL)
break;
exchange->settable_ctx_params
= OSSL_get_OP_keyexch_settable_ctx_params(fns);
paramfncnt++;
break;
}
}
if (fncnt != 4) {
if (fncnt != 4 || (paramfncnt != 0 && paramfncnt != 2)) {
/*
* 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, set_peer and set_params functions are
* optional.
* and freectx. The set_ctx_params and settable_ctx_params functions are
* optional, but if one of them is present then the other one must also
* be present. The dupctx and set_peer functions are optional.
*/
EVPerr(EVP_F_EVP_KEYEXCH_FROM_DISPATCH,
EVP_R_INVALID_PROVIDER_FUNCTIONS);

View File

@ -51,6 +51,7 @@ static void *evp_signature_from_dispatch(const char *name,
keymgmt_data->properties);
EVP_SIGNATURE *signature = NULL;
int ctxfncnt = 0, signfncnt = 0, verifyfncnt = 0, verifyrecfncnt = 0;
int gparamfncnt = 0, sparamfncnt = 0;
if (keymgmt == NULL || EVP_KEYMGMT_provider(keymgmt) != prov) {
ERR_raise(ERR_LIB_EVP, EVP_R_NO_KEYMGMT_AVAILABLE);
@ -123,21 +124,49 @@ static void *evp_signature_from_dispatch(const char *name,
break;
signature->dupctx = OSSL_get_OP_signature_dupctx(fns);
break;
case OSSL_FUNC_SIGNATURE_SET_PARAMS:
if (signature->set_params != NULL)
case OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS:
if (signature->get_ctx_params != NULL)
break;
signature->set_params = OSSL_get_OP_signature_set_params(fns);
signature->get_ctx_params
= OSSL_get_OP_signature_get_ctx_params(fns);
gparamfncnt++;
break;
case OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS:
if (signature->gettable_ctx_params != NULL)
break;
signature->gettable_ctx_params
= OSSL_get_OP_signature_gettable_ctx_params(fns);
gparamfncnt++;
break;
case OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS:
if (signature->set_ctx_params != NULL)
break;
signature->set_ctx_params
= OSSL_get_OP_signature_set_ctx_params(fns);
sparamfncnt++;
break;
case OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS:
if (signature->settable_ctx_params != NULL)
break;
signature->settable_ctx_params
= OSSL_get_OP_signature_settable_ctx_params(fns);
sparamfncnt++;
break;
}
}
if (ctxfncnt != 2
|| (signfncnt != 2 && verifyfncnt != 2 && verifyrecfncnt != 2)) {
|| (signfncnt != 2 && verifyfncnt != 2 && verifyrecfncnt != 2)
|| (gparamfncnt != 0 && gparamfncnt != 2)
|| (sparamfncnt != 0 && sparamfncnt != 2)) {
/*
* In order to be a consistent set of functions we must have at least
* a set of context functions (newctx and freectx) as well as a pair of
* "signature" functions: (sign_init, sign) or (verify_init verify) or
* (verify_recover_init, verify_recover). The dupctx and set_params
* functions are optional.
* (verify_recover_init, verify_recover). set_ctx_params and
* settable_ctx_params are optional, but if one of them is present then
* the other one must also be present. The same applies to
* get_ctx_params and gettable_ctx_params. The dupctx function is
* optional.
*/
ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS);
goto err;

View File

@ -404,15 +404,49 @@ void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx)
OPENSSL_free(ctx);
}
int EVP_PKEY_CTX_get_params(EVP_PKEY_CTX *ctx, OSSL_PARAM *params)
{
if (ctx->sigprovctx != NULL
&& ctx->signature != NULL
&& ctx->signature->get_ctx_params != NULL)
return ctx->signature->get_ctx_params(ctx->sigprovctx, params);
return 0;
}
const OSSL_PARAM *EVP_PKEY_CTX_gettable_params(EVP_PKEY_CTX *ctx)
{
if (ctx->signature != NULL
&& ctx->signature->gettable_ctx_params != NULL)
return ctx->signature->gettable_ctx_params();
return NULL;
}
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);
if (ctx->sigprovctx != NULL && ctx->signature != NULL)
return ctx->signature->set_params(ctx->sigprovctx, params);
if (ctx->exchprovctx != NULL
&& ctx->exchange != NULL
&& ctx->exchange->set_ctx_params != NULL)
return ctx->exchange->set_ctx_params(ctx->exchprovctx, params);
if (ctx->sigprovctx != NULL
&& ctx->signature != NULL
&& ctx->signature->set_ctx_params != NULL)
return ctx->signature->set_ctx_params(ctx->sigprovctx, params);
return 0;
}
const OSSL_PARAM *EVP_PKEY_CTX_settable_params(EVP_PKEY_CTX *ctx)
{
if (ctx->exchange != NULL
&& ctx->exchange->settable_ctx_params != NULL)
return ctx->exchange->settable_ctx_params();
if (ctx->signature != NULL
&& ctx->signature->settable_ctx_params != NULL)
return ctx->signature->settable_ctx_params();
return NULL;
}
#ifndef OPENSSL_NO_DH
int EVP_PKEY_CTX_set_dh_pad(EVP_PKEY_CTX *ctx, int pad)
{
@ -431,36 +465,78 @@ int EVP_PKEY_CTX_set_dh_pad(EVP_PKEY_CTX *ctx, int pad)
}
#endif
int EVP_PKEY_CTX_get_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD **md)
{
OSSL_PARAM sig_md_params[3], *p = sig_md_params;
/* 80 should be big enough */
char name[80] = "";
const EVP_MD *tmp;
if (ctx == NULL) {
ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
/* Uses the same return values as EVP_PKEY_CTX_ctrl */
return -2;
}
/* TODO(3.0): Remove this eventually when no more legacy */
if (ctx->sigprovctx == NULL)
return EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_TYPE_SIG,
EVP_PKEY_CTRL_GET_MD, 0, (void *)(md));
*p++ = OSSL_PARAM_construct_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST,
name,
sizeof(name));
*p++ = OSSL_PARAM_construct_end();
if (!EVP_PKEY_CTX_get_params(ctx, sig_md_params))
return 0;
tmp = EVP_get_digestbyname(name);
if (tmp == NULL)
return 0;
*md = tmp;
return 1;
}
int EVP_PKEY_CTX_set_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD *md)
{
OSSL_PARAM sig_md_params[3];
OSSL_PARAM sig_md_params[3], *p = sig_md_params;
size_t mdsize;
const char *name;
if (ctx == NULL) {
ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
/* Uses the same return values as EVP_PKEY_CTX_ctrl */
return -2;
}
/* TODO(3.0): Remove this eventually when no more legacy */
if (ctx->sigprovctx == NULL)
return EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_TYPE_SIG,
EVP_PKEY_CTRL_MD, 0, (void *)(md));
if (md == NULL)
return 1;
if (md == NULL) {
name = "";
mdsize = 0;
} else {
mdsize = EVP_MD_size(md);
name = EVP_MD_name(md);
}
mdsize = EVP_MD_size(md);
name = EVP_MD_name(md);
sig_md_params[0] = OSSL_PARAM_construct_utf8_string(
OSSL_SIGNATURE_PARAM_DIGEST,
/*
* Cast away the const. This is read only so should
* be safe
*/
(char *)name,
strlen(name) + 1);
sig_md_params[1] = OSSL_PARAM_construct_size_t(OSSL_SIGNATURE_PARAM_DIGEST_SIZE,
&mdsize);
sig_md_params[2] = OSSL_PARAM_construct_end();
*p++ = OSSL_PARAM_construct_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST,
/*
* Cast away the const. This is read
* only so should be safe
*/
(char *)name,
strlen(name) + 1);
*p++ = OSSL_PARAM_construct_size_t(OSSL_SIGNATURE_PARAM_DIGEST_SIZE,
&mdsize);
*p++ = OSSL_PARAM_construct_end();
return EVP_PKEY_CTX_set_params(ctx, sig_md_params);
}
static int legacy_ctrl_to_param(EVP_PKEY_CTX *ctx, int keytype, int optype,

View File

@ -2,7 +2,10 @@
=head1 NAME
EVP_PKEY_CTX_get_params,
EVP_PKEY_CTX_gettable_params,
EVP_PKEY_CTX_set_params,
EVP_PKEY_CTX_settable_params,
EVP_PKEY_CTX_ctrl,
EVP_PKEY_CTX_ctrl_str,
EVP_PKEY_CTX_ctrl_uint64,
@ -63,7 +66,10 @@ EVP_PKEY_CTX_set1_id, EVP_PKEY_CTX_get1_id, EVP_PKEY_CTX_get1_id_len
#include <openssl/evp.h>
int EVP_PKEY_CTX_get_params(EVP_PKEY_CTX *ctx, OSSL_PARAM *params);
const OSSL_PARAM *EVP_PKEY_CTX_gettable_params(EVP_PKEY_CTX *ctx);
int EVP_PKEY_CTX_set_params(EVP_PKEY_CTX *ctx, OSSL_PARAM *params);
const OSSL_PARAM *EVP_PKEY_CTX_settable_params(EVP_PKEY_CTX *ctx);
int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype,
int cmd, int p1, void *p2);
@ -144,16 +150,20 @@ EVP_PKEY_CTX_set1_id, EVP_PKEY_CTX_get1_id, EVP_PKEY_CTX_get1_id_len
=head1 DESCRIPTION
The EVP_PKEY_CTX_set_params() function sends arbitrary parameters to the
algorithm implementation.
The EVP_PKEY_CTX_get_params() and EVP_PKEY_CTX_set_params() functions get and
send arbitrary parameters from and to the algorithm implementation respectively.
Not all parameters may be supported by all providers.
See L<OSSL_PROVIDER(3)> for more information on providers.
See L<OSSL_PARAM(3)> for more information on parameters.
These functions must only be called after the EVP_PKEY_CTX has been initialised
for use in an operation (for example by L<EVP_PKEY_sign_init_ex(3)>,
L<EVP_PKEY_derive_init_ex(3)> or other similar functions).
The parameters currently supported by the default provider are:
=over 4
=item OSSL_EXCHANGE_PARAM_PAD (uint type)
=item "exchange-pad" (B<OSSL_EXCHANGE_PARAM_PAD>) <uint>
Sets the DH padding mode.
If B<OSSL_EXCHANGE_PARAM_PAD> is 1 then the shared secret is padded with zeroes
@ -161,19 +171,29 @@ up to the size of the DH prime B<p>.
If B<OSSL_EXCHANGE_PARAM_PAD> is zero (the default) then no padding is
performed.
=item OSSL_SIGNATURE_PARAM_DIGEST (UTF8 string type)
=item "digest" (B<OSSL_SIGNATURE_PARAM_DIGEST>) <utf8 string>
Sets the name of the digest algorithm used for the input to the signature
functions.
Gets and sets the name of the digest algorithm used for the input to the
signature functions.
=item OSSL_SIGNATURE_PARAM_DIGEST_SIZE (size_t type)
=item "digest-size" (B<OSSL_SIGNATURE_PARAM_DIGEST_SIZE>) <size_t>
Sets the output size of the digest algorithm used for the input to the signature
functions.
Gets and sets the output size of the digest algorithm used for the input to the
signature functions.
The internal algorithm that supports this parameter is DSA.
=back
EVP_PKEY_CTX_gettable_params() and EVP_PKEY_CTX_settable_params() gets a
constant B<OSSL_PARAM> array that decribes the gettable and
settable parameters for the current algorithm implementation, i.e. parameters
that can be used with EVP_PKEY_CTX_get_params() and EVP_PKEY_CTX_set_params()
respectively.
See L<OSSL_PARAM(3)> for the use of B<OSSL_PARAM> as parameter descriptor.
These functions must only be called after the EVP_PKEY_CTX has been initialised
for use in an operation (for example by L<EVP_PKEY_sign_init_ex(3)>,
L<EVP_PKEY_derive_init_ex(3)> or other similar functions).
The function EVP_PKEY_CTX_ctrl() sends a control operation to the context
B<ctx>. The key type used must match B<keytype> if it is not -1. The parameter
B<optype> is a mask indicating which operations the control can be applied to.
@ -199,13 +219,13 @@ B<pkeyutl>, B<genpkey> and B<req> commands.
The function EVP_PKEY_CTX_md() sends a message digest control operation
to the context B<ctx>. The message digest is specified by its name B<md>.
All the remaining "functions" are implemented as macros.
The EVP_PKEY_CTX_set_signature_md() macro sets the message digest type used
The EVP_PKEY_CTX_set_signature_md() function sets the message digest type used
in a signature. It can be used in the RSA, DSA and ECDSA algorithms.
The EVP_PKEY_CTX_get_signature_md() macro gets the message digest type used in a
signature. It can be used in the RSA, DSA and ECDSA algorithms.
The EVP_PKEY_CTX_get_signature_md() function gets the message digest type used
in a signature. It can be used in the RSA, DSA and ECDSA algorithms.
All the remaining "functions" are implemented as macros.
Key generation typically involves setting up parameters to be used and
generating the private and public key data. Some algorithm implementations
@ -471,9 +491,15 @@ allocate adequate memory space for the B<id> before calling EVP_PKEY_CTX_get1_id
=head1 RETURN VALUES
EVP_PKEY_CTX_ctrl() and its macros return a positive value for success and 0
or a negative value for failure. In particular a return value of -2
indicates the operation is not supported by the public key algorithm.
EVP_PKEY_CTX_set_params() returns 1 for success or 0 otherwise.
EVP_PKEY_CTX_settable_params() returns an OSSL_PARAM array on success or NULL on
error.
It may also return NULL if there are no settable parameters available.
EVP_PKEY_CTX_set_signature_md(), EVP_PKEY_CTX_set_dh_pad(), EVP_PKEY_CTX_ctrl()
and its macros return a positive value for success and 0 or a negative value for
failure. In particular a return value of -2 indicates the operation is not
supported by the public key algorithm.
=head1 SEE ALSO
@ -492,8 +518,9 @@ The
EVP_PKEY_CTX_set1_id(), EVP_PKEY_CTX_get1_id() and EVP_PKEY_CTX_get1_id_len()
macros were added in 1.1.1, other functions were added in OpenSSL 1.0.0.
EVP_PKEY_CTX_set_dh_pad() was a macro in OpenSSL 1.1.1 and below.
From OpenSSL 3.0 it is a function.
EVP_PKEY_CTX_get_signature_md(), EVP_PKEY_CTX_set_signature_md() and
EVP_PKEY_CTX_set_dh_pad() were macros in OpenSSL 1.1.1 and below. From OpenSSL
3.0 they are functions.
=head1 COPYRIGHT

View File

@ -29,8 +29,8 @@ provider-keyexch - The keyexch library E<lt>-E<gt> provider functions
size_t outlen);
/* Key Exchange parameters */
int OP_keyexch_set_params(void *ctx, const OSSL_PARAM params[]);
int OP_keyexch_set_ctx_params(void *ctx, const OSSL_PARAM params[]);
const OSSL_PARAM *OP_keyexch_settable_ctx_params(void);
=head1 DESCRIPTION
@ -61,15 +61,16 @@ For example, the "function" OP_keyexch_newctx() has these:
B<OSSL_DISPATCH> arrays are indexed by numbers that are provided as
macros in L<openssl-core_numbers.h(7)>, as follows:
OP_keyexch_newctx OSSL_FUNC_KEYEXCH_NEWCTX
OP_keyexch_freectx OSSL_FUNC_KEYEXCH_FREECTX
OP_keyexch_dupctx OSSL_FUNC_KEYEXCH_DUPCTX
OP_keyexch_newctx OSSL_FUNC_KEYEXCH_NEWCTX
OP_keyexch_freectx OSSL_FUNC_KEYEXCH_FREECTX
OP_keyexch_dupctx OSSL_FUNC_KEYEXCH_DUPCTX
OP_keyexch_init OSSL_FUNC_KEYEXCH_INIT
OP_keyexch_set_peer OSSL_FUNC_KEYEXCH_SET_PEER
OP_keyexch_derive OSSL_FUNC_KEYEXCH_DERIVE
OP_keyexch_init OSSL_FUNC_KEYEXCH_INIT
OP_keyexch_set_peer OSSL_FUNC_KEYEXCH_SET_PEER
OP_keyexch_derive OSSL_FUNC_KEYEXCH_DERIVE
OP_keyexch_set_params OSSL_FUNC_KEYEXCH_SET_PARAMS
OP_keyexch_set_ctx_params OSSL_FUNC_KEYEXCH_SET_CTX_PARAMS
OP_keyexch_settable_ctx_params OSSL_FUNC_KEYEXCH_SETTABLE_CTX_PARAMS
A key exchange algorithm implementation may not implement all of these functions.
In order to be a consistent set of functions a provider must implement
@ -127,8 +128,8 @@ written to B<*secretlen>.
See L<OSSL_PARAM(3)> for further details on the parameters structure used by
the OP_keyexch_set_params() function.
OP_keyexch_set_params() sets key exchange parameters associated with the given
provider side key exchange context B<ctx> to B<params>.
OP_keyexch_set_ctx_params() sets key exchange parameters associated with the
given provider side key exchange context B<ctx> to B<params>.
Any parameter settings are additional to any that were previously set.
Parameters currently recognised by built-in key exchange algorithms are as
@ -151,6 +152,11 @@ possible secret size.
=back
OP_keyexch_settable_ctx_params() gets a constant B<OSSL_PARAM> array that
decribes the settable parameters, i.e. parameters that can be used with
OP_signature_set_ctx_params().
See L<OSSL_PARAM(3)> for the use of B<OSSL_PARAM> as parameter descriptor.
=head1 RETURN VALUES
OP_keyexch_newctx() and OP_keyexch_dupctx() should return the newly created

View File

@ -39,8 +39,10 @@ provider-signature - The signature library E<lt>-E<gt> provider functions
const unsigned char *sig, size_t siglen);
/* Signature parameters */
int OP_signature_set_params(void *ctx, const OSSL_PARAM params[]);
int OP_signature_get_ctx_params(void *ctx, OSSL_PARAM params[]);
const OSSL_PARAM *OP_signature_gettable_ctx_params(void);
int OP_signature_set_ctx_params(void *ctx, const OSSL_PARAM params[]);
const OSSL_PARAM *OP_signature_settable_ctx_params(void);
=head1 DESCRIPTION
@ -86,7 +88,10 @@ macros in L<openssl-core_numbers.h(7)>, as follows:
OP_signature_verify_recover_init OSSL_FUNC_SIGNATURE_VERIFY_RECOVER_INIT
OP_signature_verify_recover OSSL_FUNC_SIGNATURE_VERIFY_RECOVER
OP_signature_set_params OSSL_FUNC_SIGNATURE_SET_PARAMS
OP_signature_get_ctx_params OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS
OP_signature_gettable_ctx_params OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS
OP_signature_set_ctx_params OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS
OP_signature_settable_ctx_params OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS
A signature algorithm implementation may not implement all of these functions.
In order to be a consistent set of functions a provider must implement
@ -174,10 +179,12 @@ the B<routlen> parameter.
=head2 Signature Parameters
See L<OSSL_PARAM(3)> for further details on the parameters structure used by
the OP_signature_set_params() function.
the OP_signature_get_ctx_params() and OP_signature_set_ctx_params() functions.
OP_signature_set_params() sets signature parameters associated with the given
provider side key exchange context B<ctx> to B<params>.
OP_signature_get_ctx_params() gets signature parameters associated with the
given provider side signature context B<ctx> and stored them in B<params>.
OP_signature_set_ctx_params() sets the signature parameters associated with the
given provider side signature context B<ctx> to B<params>.
Any parameter settings are additional to any that were previously set.
Parameters currently recognised by built-in signature algorithms are as
@ -187,27 +194,30 @@ algorithms:
=over 4
=item B<OSSL_SIGNATURE_PARAM_DIGEST> (UTF8 string)
=item "digest" (B<OSSL_SIGNATURE_PARAM_DIGEST>) <utf8 string>
Sets the name of the digest algorithm used for the input to the signature
Get or sets the name of the digest algorithm used for the input to the signature
functions.
=item B<OSSL_SIGNATURE_PARAM_DIGEST_SIZE> (size_t)
=item "digest-size" (B<OSSL_SIGNATURE_PARAM_DIGEST_SIZE>) <size_t>
Sets the output size of the digest algorithm used for the input to the signature
functions.
Gets or sets the output size of the digest algorithm used for the input to the
signature functions.
=back
OP_signature_gettable_ctx_params() and OP_signature_settable_ctx_params() get a
constant B<OSSL_PARAM> array that decribes the gettable and settable parameters,
i.e. parameters that can be used with OP_signature_get_ctx_params() and
OP_signature_set_ctx_params() respectively.
See L<OSSL_PARAM(3)> for the use of B<OSSL_PARAM> as parameter descriptor.
=head1 RETURN VALUES
OP_signature_newctx() and OP_signature_dupctx() should return the newly created
provider side signature, or NULL on failure.
OP_signature_sign_init(), OP_signature_sign(), OP_signature_verify_init(),
OP_signature_verify(), OP_signature_verify_recover_init(),
OP_signature_verify_recover() and OP_signature_set_params() should return 1 for
success or 0 on error.
All other functions should return 1 for success or 0 on error.
=head1 SEE ALSO

View File

@ -389,7 +389,8 @@ OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, OP_keymgmt_exportkey_types, (void))
# 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
# define OSSL_FUNC_KEYEXCH_SET_CTX_PARAMS 7
# define OSSL_FUNC_KEYEXCH_SETTABLE_CTX_PARAMS 8
OSSL_CORE_MAKE_FUNC(void *, OP_keyexch_newctx, (void *provctx))
OSSL_CORE_MAKE_FUNC(int, OP_keyexch_init, (void *ctx, void *provkey))
@ -398,8 +399,10 @@ OSSL_CORE_MAKE_FUNC(int, OP_keyexch_derive, (void *ctx, unsigned char *secret,
OSSL_CORE_MAKE_FUNC(int, OP_keyexch_set_peer, (void *ctx, void *provkey))
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,
const OSSL_PARAM params[]))
OSSL_CORE_MAKE_FUNC(int, OP_keyexch_set_ctx_params, (void *ctx,
const OSSL_PARAM params[]))
OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, OP_keyexch_settable_ctx_params,
(void))
/* Signature */
@ -412,7 +415,10 @@ OSSL_CORE_MAKE_FUNC(int, OP_keyexch_set_params, (void *ctx,
# define OSSL_FUNC_SIGNATURE_VERIFY_RECOVER 7
# define OSSL_FUNC_SIGNATURE_FREECTX 8
# define OSSL_FUNC_SIGNATURE_DUPCTX 9
# define OSSL_FUNC_SIGNATURE_SET_PARAMS 10
# define OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS 10
# define OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS 11
# define OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS 12
# define OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS 13
OSSL_CORE_MAKE_FUNC(void *, OP_signature_newctx, (void *provctx))
OSSL_CORE_MAKE_FUNC(int, OP_signature_sign_init, (void *ctx, void *provkey))
@ -436,8 +442,14 @@ OSSL_CORE_MAKE_FUNC(int, OP_signature_verify_recover, (void *ctx,
size_t siglen))
OSSL_CORE_MAKE_FUNC(void, OP_signature_freectx, (void *ctx))
OSSL_CORE_MAKE_FUNC(void *, OP_signature_dupctx, (void *ctx))
OSSL_CORE_MAKE_FUNC(int, OP_signature_set_params, (void *ctx,
const OSSL_PARAM params[]))
OSSL_CORE_MAKE_FUNC(int, OP_signature_get_ctx_params,
(void *ctx, OSSL_PARAM params[]))
OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, OP_signature_gettable_ctx_params,
(void))
OSSL_CORE_MAKE_FUNC(int, OP_signature_set_ctx_params,
(void *ctx, const OSSL_PARAM params[]))
OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, OP_signature_settable_ctx_params,
(void))
# ifdef __cplusplus
}

View File

@ -1337,6 +1337,7 @@ void EVP_PKEY_asn1_set_security_bits(EVP_PKEY_ASN1_METHOD *ameth,
int (*pkey_security_bits) (const EVP_PKEY
*pk));
int EVP_PKEY_CTX_get_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD **md);
int EVP_PKEY_CTX_set_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD *md);
# define EVP_PKEY_OP_UNDEFINED 0
@ -1364,10 +1365,6 @@ int EVP_PKEY_CTX_set_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD *md);
# define EVP_PKEY_OP_TYPE_GEN \
(EVP_PKEY_OP_PARAMGEN | EVP_PKEY_OP_KEYGEN)
# define EVP_PKEY_CTX_get_signature_md(ctx, pmd) \
EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_TYPE_SIG, \
EVP_PKEY_CTRL_GET_MD, 0, (void *)(pmd))
# define EVP_PKEY_CTX_set_mac_key(ctx, key, len) \
EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_KEYGEN, \
EVP_PKEY_CTRL_SET_MAC_KEY, len, (void *)(key))
@ -1427,7 +1424,10 @@ 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_get_params(EVP_PKEY_CTX *ctx, OSSL_PARAM *params);
const OSSL_PARAM *EVP_PKEY_CTX_gettable_params(EVP_PKEY_CTX *ctx);
int EVP_PKEY_CTX_set_params(EVP_PKEY_CTX *ctx, OSSL_PARAM *params);
const OSSL_PARAM *EVP_PKEY_CTX_settable_params(EVP_PKEY_CTX *ctx);
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

@ -20,6 +20,8 @@ static OSSL_OP_keyexch_set_peer_fn dh_set_peer;
static OSSL_OP_keyexch_derive_fn dh_derive;
static OSSL_OP_keyexch_freectx_fn dh_freectx;
static OSSL_OP_keyexch_dupctx_fn dh_dupctx;
static OSSL_OP_keyexch_set_ctx_params_fn dh_set_ctx_params;
static OSSL_OP_keyexch_settable_ctx_params_fn dh_settable_ctx_params;
/*
* What's passed as an actual key is defined by the KEYMGMT interface.
@ -124,7 +126,7 @@ static void *dh_dupctx(void *vpdhctx)
return dstctx;
}
static int dh_set_params(void *vpdhctx, const OSSL_PARAM params[])
static int dh_set_ctx_params(void *vpdhctx, const OSSL_PARAM params[])
{
PROV_DH_CTX *pdhctx = (PROV_DH_CTX *)vpdhctx;
const OSSL_PARAM *p;
@ -140,6 +142,16 @@ static int dh_set_params(void *vpdhctx, const OSSL_PARAM params[])
return 1;
}
static const OSSL_PARAM known_settable_ctx_params[] = {
OSSL_PARAM_int(OSSL_EXCHANGE_PARAM_PAD, NULL),
OSSL_PARAM_END
};
static const OSSL_PARAM *dh_settable_ctx_params(void)
{
return known_settable_ctx_params;
}
const OSSL_DISPATCH dh_keyexch_functions[] = {
{ OSSL_FUNC_KEYEXCH_NEWCTX, (void (*)(void))dh_newctx },
{ OSSL_FUNC_KEYEXCH_INIT, (void (*)(void))dh_init },
@ -147,6 +159,8 @@ const OSSL_DISPATCH dh_keyexch_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 },
{ OSSL_FUNC_KEYEXCH_SET_CTX_PARAMS, (void (*)(void))dh_set_ctx_params },
{ OSSL_FUNC_KEYEXCH_SETTABLE_CTX_PARAMS,
(void (*)(void))dh_settable_ctx_params },
{ 0, NULL }
};

View File

@ -20,7 +20,10 @@ static OSSL_OP_signature_verify_init_fn dsa_signature_init;
static OSSL_OP_signature_sign_fn dsa_sign;
static OSSL_OP_signature_freectx_fn dsa_freectx;
static OSSL_OP_signature_dupctx_fn dsa_dupctx;
static OSSL_OP_signature_set_params_fn dsa_set_params;
static OSSL_OP_signature_get_ctx_params_fn dsa_get_ctx_params;
static OSSL_OP_signature_gettable_ctx_params_fn dsa_gettable_ctx_params;
static OSSL_OP_signature_set_ctx_params_fn dsa_set_ctx_params;
static OSSL_OP_signature_settable_ctx_params_fn dsa_settable_ctx_params;
/*
* What's passed as an actual key is defined by the KEYMGMT interface.
@ -31,6 +34,8 @@ static OSSL_OP_signature_set_params_fn dsa_set_params;
typedef struct {
DSA *dsa;
size_t mdsize;
/* Should be big enough */
char mdname[80];
} PROV_DSA_CTX;
static void *dsa_newctx(void *provctx)
@ -116,24 +121,74 @@ static void *dsa_dupctx(void *vpdsactx)
return dstctx;
}
static int dsa_set_params(void *vpdsactx, const OSSL_PARAM params[])
static int dsa_get_ctx_params(void *vpdsactx, OSSL_PARAM *params)
{
PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx;
OSSL_PARAM *p;
if (pdsactx == NULL || params == NULL)
return 0;
p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_DIGEST_SIZE);
if (p != NULL && !OSSL_PARAM_set_size_t(p, pdsactx->mdsize))
return 0;
p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_DIGEST);
if (p != NULL && !OSSL_PARAM_set_utf8_string(p, pdsactx->mdname))
return 0;
return 1;
}
static const OSSL_PARAM known_gettable_ctx_params[] = {
OSSL_PARAM_size_t(OSSL_SIGNATURE_PARAM_DIGEST_SIZE, NULL),
OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST, NULL, 0),
OSSL_PARAM_END
};
static const OSSL_PARAM *dsa_gettable_ctx_params(void)
{
return known_gettable_ctx_params;
}
static int dsa_set_ctx_params(void *vpdsactx, const OSSL_PARAM params[])
{
PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx;
const OSSL_PARAM *p;
size_t mdsize;
char *mdname;
if (pdsactx == NULL || params == NULL)
return 0;
p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_DIGEST_SIZE);
if (p == NULL || !OSSL_PARAM_get_size_t(p, &mdsize))
if (p != NULL && !OSSL_PARAM_get_size_t(p, &pdsactx->mdsize))
return 0;
pdsactx->mdsize = mdsize;
/*
* We never actually use the mdname, but we do support getting it later.
* This can be useful for applications that want to know the MD that they
* previously set.
*/
p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_DIGEST);
mdname = pdsactx->mdname;
if (p != NULL
&& !OSSL_PARAM_get_utf8_string(p, &mdname, sizeof(pdsactx->mdname)))
return 0;
return 1;
}
static const OSSL_PARAM known_settable_ctx_params[] = {
OSSL_PARAM_size_t(OSSL_SIGNATURE_PARAM_DIGEST_SIZE, NULL),
OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST, NULL, 0),
OSSL_PARAM_END
};
static const OSSL_PARAM *dsa_settable_ctx_params(void)
{
return known_settable_ctx_params;
}
const OSSL_DISPATCH dsa_signature_functions[] = {
{ OSSL_FUNC_SIGNATURE_NEWCTX, (void (*)(void))dsa_newctx },
{ OSSL_FUNC_SIGNATURE_SIGN_INIT, (void (*)(void))dsa_signature_init },
@ -142,6 +197,11 @@ const OSSL_DISPATCH dsa_signature_functions[] = {
{ OSSL_FUNC_SIGNATURE_VERIFY, (void (*)(void))dsa_verify },
{ OSSL_FUNC_SIGNATURE_FREECTX, (void (*)(void))dsa_freectx },
{ OSSL_FUNC_SIGNATURE_DUPCTX, (void (*)(void))dsa_dupctx },
{ OSSL_FUNC_SIGNATURE_SET_PARAMS, (void (*)(void))dsa_set_params },
{ OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS, (void (*)(void))dsa_get_ctx_params },
{ OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS,
(void (*)(void))dsa_gettable_ctx_params },
{ OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS, (void (*)(void))dsa_set_ctx_params },
{ OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS,
(void (*)(void))dsa_settable_ctx_params },
{ 0, NULL }
};

View File

@ -19,6 +19,8 @@
#include <openssl/pem.h>
#include <openssl/kdf.h>
#include <openssl/provider.h>
#include <openssl/core_names.h>
#include <openssl/dsa.h>
#include "testutil.h"
#include "internal/nelem.h"
#include "internal/evp_int.h"
@ -1393,6 +1395,117 @@ static int test_EVP_CIPHER_fetch(int tst)
return ret;
}
/* Test getting and setting parameters on an EVP_PKEY_CTX */
static int test_EVP_PKEY_CTX_get_set_params(void)
{
EVP_PKEY_CTX *ctx = NULL;
EVP_SIGNATURE *dsaimpl = NULL;
const OSSL_PARAM *params;
OSSL_PARAM ourparams[2], *param = ourparams;
DSA *dsa = NULL;
BIGNUM *p = NULL, *q = NULL, *g = NULL;
EVP_PKEY *pkey = NULL;
int ret = 0;
const EVP_MD *md;
size_t mdsize = SHA512_DIGEST_LENGTH;
/*
* Setup the parameters for our DSA object. For our purposes they don't have
* to actually be *valid* parameters. We just need to set something. We
* don't even need a pub_key/priv_key.
*/
dsa = DSA_new();
p = BN_new();
q = BN_new();
g = BN_new();
if (!TEST_ptr(dsa)
|| !TEST_ptr(p)
|| !TEST_ptr(q)
|| !TEST_ptr(g)
|| !DSA_set0_pqg(dsa, p, q, g))
goto err;
p = q = g = NULL;
pkey = EVP_PKEY_new();
if (!TEST_ptr(pkey)
|| !TEST_true(EVP_PKEY_assign_DSA(pkey, dsa)))
goto err;
dsa = NULL;
/* Initialise a sign operation */
ctx = EVP_PKEY_CTX_new(pkey, NULL);
dsaimpl = EVP_SIGNATURE_fetch(NULL, "DSA", NULL);
if (!TEST_ptr(ctx)
|| !TEST_ptr(dsaimpl)
|| !TEST_int_gt(EVP_PKEY_sign_init_ex(ctx, dsaimpl), 0))
goto err;
/*
* We should be able to query the parameters now. The default DSA
* implementation supports exactly one parameter - so we expect to see that
* returned and no more.
*/
params = EVP_PKEY_CTX_settable_params(ctx);
if (!TEST_ptr(params)
|| !TEST_int_eq(strcmp(params[0].key,
OSSL_SIGNATURE_PARAM_DIGEST_SIZE), 0)
|| !TEST_int_eq(strcmp(params[1].key, OSSL_SIGNATURE_PARAM_DIGEST),
0)
/* The final key should be NULL */
|| !TEST_ptr_null(params[2].key))
goto err;
/* Gettable params are the same as the settable ones */
params = EVP_PKEY_CTX_gettable_params(ctx);
if (!TEST_ptr(params)
|| !TEST_int_eq(strcmp(params[0].key,
OSSL_SIGNATURE_PARAM_DIGEST_SIZE), 0)
|| !TEST_int_eq(strcmp(params[1].key, OSSL_SIGNATURE_PARAM_DIGEST),
0)
/* The final key should be NULL */
|| !TEST_ptr_null(params[2].key))
goto err;
/*
* Test getting and setting params via EVP_PKEY_CTX_set_params() and
* EVP_PKEY_CTX_get_params()
*/
*param++ = OSSL_PARAM_construct_size_t(OSSL_SIGNATURE_PARAM_DIGEST_SIZE,
&mdsize);
*param++ = OSSL_PARAM_construct_end();
if (!TEST_true(EVP_PKEY_CTX_set_params(ctx, ourparams)))
goto err;
mdsize = 0;
if (!TEST_true(EVP_PKEY_CTX_get_params(ctx, ourparams))
|| !TEST_size_t_eq(mdsize, SHA512_DIGEST_LENGTH))
goto err;
/*
* Test the TEST_PKEY_CTX_set_signature_md() and
* TEST_PKEY_CTX_get_signature_md() functions
*/
if (!TEST_int_gt(EVP_PKEY_CTX_set_signature_md(ctx, EVP_sha256()), 0)
|| !TEST_int_gt(EVP_PKEY_CTX_get_signature_md(ctx, &md), 0)
|| !TEST_ptr_eq(md, EVP_sha256()))
goto err;
ret = 1;
err:
EVP_PKEY_CTX_free(ctx);
EVP_SIGNATURE_free(dsaimpl);
EVP_PKEY_free(pkey);
DSA_free(dsa);
BN_free(p);
BN_free(q);
BN_free(g);
return ret;
}
int setup_tests(void)
{
ADD_TEST(test_EVP_DigestSignInit);
@ -1429,5 +1542,6 @@ int setup_tests(void)
ADD_ALL_TESTS(test_EVP_MD_fetch, 5);
ADD_ALL_TESTS(test_EVP_CIPHER_fetch, 5);
#endif
ADD_TEST(test_EVP_PKEY_CTX_get_set_params);
return 1;
}

View File

@ -4748,3 +4748,7 @@ EVP_PKEY_sign_init_ex 4864 3_0_0 EXIST::FUNCTION:
EVP_PKEY_CTX_set_signature_md 4865 3_0_0 EXIST::FUNCTION:
EVP_PKEY_verify_init_ex 4866 3_0_0 EXIST::FUNCTION:
EVP_PKEY_verify_recover_init_ex 4867 3_0_0 EXIST::FUNCTION:
EVP_PKEY_CTX_get_signature_md 4868 3_0_0 EXIST::FUNCTION:
EVP_PKEY_CTX_get_params 4869 3_0_0 EXIST::FUNCTION:
EVP_PKEY_CTX_gettable_params 4870 3_0_0 EXIST::FUNCTION:
EVP_PKEY_CTX_settable_params 4871 3_0_0 EXIST::FUNCTION: