=pod

=head1 NAME

EVP_PKEY_CTX_new, EVP_PKEY_CTX_new_id, EVP_PKEY_CTX_new_from_name,
EVP_PKEY_CTX_new_from_pkey, EVP_PKEY_CTX_dup, EVP_PKEY_CTX_free,
EVP_PKEY_CTX_is_a
- public key algorithm context functions

=head1 SYNOPSIS

 #include <openssl/evp.h>

 EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e);
 EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e);
 EVP_PKEY_CTX *EVP_PKEY_CTX_new_from_name(OSSL_LIB_CTX *libctx,
                                          const char *name,
                                          const char *propquery);
 EVP_PKEY_CTX *EVP_PKEY_CTX_new_from_pkey(OSSL_LIB_CTX *libctx,
                                          EVP_PKEY *pkey,
                                          const char *propquery);
 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_is_a(EVP_PKEY_CTX *ctx, const char *keytype);

=head1 DESCRIPTION

The EVP_PKEY_CTX_new() function allocates public key algorithm context using
the I<pkey> key type and ENGINE I<e>.

The EVP_PKEY_CTX_new_id() function allocates public key algorithm context
using the key type specified by I<id> and ENGINE I<e>.

The EVP_PKEY_CTX_new_from_name() function allocates a public key algorithm
context using the library context I<libctx> (see L<OSSL_LIB_CTX(3)>), the
key type specified by I<name> and the property query I<propquery>.  None
of the arguments are duplicated, so they  must remain unchanged for the
lifetime of the returned B<EVP_PKEY_CTX> or of any of its duplicates.  Read
further about the possible names in L</NOTES> below.

The EVP_PKEY_CTX_new_from_pkey() function allocates a public key algorithm
context using the library context I<libctx> (see L<OSSL_LIB_CTX(3)>) and the
algorithm specified by I<pkey> and the property query I<propquery>. None of the
arguments are duplicated, so they must remain unchanged for the lifetime of the
returned B<EVP_PKEY_CTX> or any of its duplicates.

EVP_PKEY_CTX_new_id() and EVP_PKEY_CTX_new_from_name() are normally
used when no B<EVP_PKEY> structure is associated with the operations,
for example during parameter generation or key generation for some
algorithms.

EVP_PKEY_CTX_dup() duplicates the context I<ctx>. It is not supported for a
keygen operation.

EVP_PKEY_CTX_free() frees up the context I<ctx>.
If I<ctx> is NULL, nothing is done.

EVP_PKEY_is_a() checks if the key type associated with I<ctx> is I<keytype>.

=head1 NOTES

=head2 On B<EVP_PKEY_CTX>

The B<EVP_PKEY_CTX> structure is an opaque public key algorithm context used
by the OpenSSL high-level public key API. Contexts B<MUST NOT> be shared between
threads: that is it is not permissible to use the same context simultaneously
in two threads.

=head2 On Key Types

We mention "key type" in this manual, which is the same
as "algorithm" in most cases, allowing either term to be used
interchangeably.  There are algorithms where the I<key type> and the
I<algorithm> of the operations that use the keys are not the same,
such as EC keys being used for ECDSA and ECDH operations.

Key types are given in two different manners:

=over 4

=item Legacy NID or EVP_PKEY type

This is the I<id> used with EVP_PKEY_CTX_new_id().

These are B<EVP_PKEY_RSA>, B<EVP_PKEY_RSA_PSS>, B<EVP_PKEY_DSA>,
B<EVP_PKEY_DH>, B<EVP_PKEY_EC>, B<EVP_PKEY_SM2>, B<EVP_PKEY_X25519>,
B<EVP_PKEY_X448>, and are used by legacy methods.

=item Name strings

This is the I<name> used with EVP_PKEY_CTX_new_from_name().

These are names like "RSA", "DSA", and what's available depends on what
providers are currently accessible.

The OpenSSL providers offer a set of key types available this way, please
see L<OSSL_PROVIDER-FIPS(7)> and L<OSSL_PROVIDER-default(7)> and related
documentation for more information.

=back

=head1 RETURN VALUES

EVP_PKEY_CTX_new(), EVP_PKEY_CTX_new_id() and EVP_PKEY_CTX_dup() return either
the newly allocated B<EVP_PKEY_CTX> structure or B<NULL> if an error occurred.

EVP_PKEY_CTX_free() does not return a value.

EVP_PKEY_CTX_is_a() returns 1 for true and 0 for false.

=head1 SEE ALSO

L<EVP_PKEY_new(3)>

=head1 HISTORY

The EVP_PKEY_CTX_new(), EVP_PKEY_CTX_new_id(), EVP_PKEY_CTX_dup() and
EVP_PKEY_CTX_free() functions were added in OpenSSL 1.0.0.

The EVP_PKEY_CTX_new_from_name() and EVP_PKEY_CTX_new_from_pkey() functions were
added in OpenSSL 3.0.

=head1 COPYRIGHT

Copyright 2006-2021 The OpenSSL Project Authors. All Rights Reserved.

Licensed under the Apache License 2.0 (the "License").  You may not use
this file except in compliance with the License.  You can obtain a copy
in the file LICENSE in the source distribution or at
L<https://www.openssl.org/source/license.html>.

=cut
