EVP_PKEY_KEYGEN(3)

πŸ“¦ version 4.1.0, in opensuse-leap 16.0

πŸ’… EVP_PKEY_KEYGEN β€” the one where your keys are literally born

okay so this page lives in Library Functions Manual and it's all about making keys and parameters, bestie. It's giving ✨ creation energy ✨. Buckle up, we're gonna be so good at this.

✨ NAME ✨

EVP_PKEY_keygen_init, EVP_PKEY_keygen, EVP_PKEY_paramgen_init, EVP_PKEY_paramgen, EVP_PKEY_gen_cb, EVP_PKEY_CTX_set_cb, EVP_PKEY_CTX_get_cb, EVP_PKEY_CTX_set0_keygen_info, EVP_PKEY_CTX_get_keygen_info, EVP_PKEY_CTX_set_app_data, EVP_PKEY_CTX_get_app_data, EVP_PKEY_CTX_set_data, EVP_PKEY_CTX_get_data β€” key and parameter generation functions πŸŽ€

πŸ’– SYNOPSIS πŸ’–

#include <openssl/evp.h>

int
EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx);

int
EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey);

int
EVP_PKEY_paramgen_init(EVP_PKEY_CTX *ctx);

int
EVP_PKEY_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey);

typedef int
EVP_PKEY_gen_cb(EVP_PKEY_CTX *ctx);

void
EVP_PKEY_CTX_set_cb(EVP_PKEY_CTX *ctx, EVP_PKEY_gen_cb *cb);

EVP_PKEY_gen_cb *
EVP_PKEY_CTX_get_cb(EVP_PKEY_CTX *ctx);

void
EVP_PKEY_CTX_set0_keygen_info(EVP_PKEY_CTX *ctx, int *dat, int datlen);

int
EVP_PKEY_CTX_get_keygen_info(EVP_PKEY_CTX *ctx, int idx);

void
EVP_PKEY_CTX_set_app_data(EVP_PKEY_CTX *ctx, void *app_data);

void *
EVP_PKEY_CTX_get_app_data(EVP_PKEY_CTX *ctx);

void
EVP_PKEY_CTX_set_data(EVP_PKEY_CTX *ctx, void *data);

void *
EVP_PKEY_CTX_get_data(EVP_PKEY_CTX *ctx);

🌸 DESCRIPTION 🌸

okay so first up: EVP_PKEY_keygen_init() initializes a public key algorithm context, using key ctx->pkey, for a key generation operation. Setup era πŸ’…

Then EVP_PKEY_keygen() actually performs the key generation operation. Where does the shiny new key go? Into ppkey. Slay.

The functions EVP_PKEY_paramgen_init() and EVP_PKEY_paramgen() are literally the same vibe, except parameters get generated instead. Same energy, different output πŸ¦‹

EVP_PKEY_CTX_set_cb() and EVP_PKEY_CTX_get_cb() set and retrieve the key or parameter generation callback, respectively. Setter and getter, bestie pair, iconic.

EVP_PKEY_CTX_set0_keygen_info() sets the parameters associated with the generation operation to the array dat, which contains datlen integer parameters. Important: the caller retains ownership of the dat array β€” the library will never free it. Not even once. Not even a little. πŸ™ˆ

EVP_PKEY_CTX_get_keygen_info() returns parameters associated with the generation operation. If idx is -1, you get the total number of parameters available back. Any non-negative value returns the value of that parameter. But hear me: EVP_PKEY_CTX_get_keygen_info() with a non-negative value for idx should only be called within the generation callback. That's the rule, no cap.

If the callback returns 0, then the key generation operation is aborted and an error occurs. This might occur during a time consuming operation where a user clicks on a "cancel" button. Very "user pressed the X, respect it" of them πŸ’€

EVP_PKEY_CTX_set_app_data() and EVP_PKEY_CTX_get_app_data() set and retrieve an opaque pointer. Why do you care? Because you can use it to stash some application defined value that you can grab later in the callback β€” for example a handle which is used to update a "progress dialog". Progress bar representation, we love to see it 🌈

The deprecated functions EVP_PKEY_CTX_set_data() and EVP_PKEY_CTX_get_data() set and retrieve a different opaque pointer β€” and that one is ignored by the library. Yeah. Ignored. It's giving decoration πŸŽ€

After the call to EVP_PKEY_keygen_init() or EVP_PKEY_paramgen_init(), algorithm specific control operations can be performed to set any appropriate parameters for the operation. That's your moment to customize ✨

Also handy: EVP_PKEY_keygen() and EVP_PKEY_paramgen() can be called more than once on the same context if several operations are performed using the same parameters. Reuse, re-run, re-slay πŸ‘‘

The meaning of the parameters passed to the callback will depend on the algorithm and the specific implementation of the algorithm. Some might not give any useful information at all during key or parameter generation. Others might not even call the callback. Yeah, some algorithms are just like that 😭

The operation performed by key or parameter generation depends on the algorithm used. In some cases (e.g. EC with a supplied named curve) the "generation" option merely sets the appropriate fields in an EVP_PKEY structure. So it's more of a "fill in the blanks" than a whole birth scene, iykyk.

In OpenSSL, an EVP_PKEY structure containing a private key also contains the public key components and parameters (if any). An OpenSSL private key is equivalent to what some libraries call a "key pair". And a private key can be used in functions which require the use of a public key or parameters. Multitasking icon πŸ’…


⭐ RETURN VALUES ⭐

EVP_PKEY_keygen_init(), EVP_PKEY_paramgen_init(), EVP_PKEY_keygen(), and EVP_PKEY_paramgen() return 1 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. Rude, but okay.

Callback functions of the type EVP_PKEY_gen_cb() are supposed to return 1 on success or 0 on error.

EVP_PKEY_CTX_get_cb() returns a function pointer to the currently installed callback function, or NULL if no callback function is installed. Empty slot energy.

EVP_PKEY_CTX_get_keygen_info() returns the number of available parameters if idx is -1, one of these parameters if idx is greater than or equal to zero but less than the number of available parameters, or 0 otherwise. Simple as 🫢

EVP_PKEY_CTX_get_app_data() and EVP_PKEY_CTX_get_data() return the pointer that was last passed to the corresponding set function, or NULL if the corresponding set function was never called on ctx.


πŸ¦‹ EXAMPLES πŸ¦‹

Generate a 2048-bit RSA key:

#include <openssl/evp.h>
#include <openssl/rsa.h>

EVP_PKEY_CTX *ctx;
EVP_PKEY *pkey = NULL;

ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL);
if (!ctx)
        /* Error occurred */
if (EVP_PKEY_keygen_init(ctx) <= 0)
        /* Error */
if (EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, 2048) <= 0)
        /* Error */

/* Generate key */
if (EVP_PKEY_keygen(ctx, &pkey) <= 0)
        /* Error */

Generate a key from a set of parameters:

#include <openssl/evp.h>
#include <openssl/rsa.h>

EVP_PKEY_CTX *ctx;
EVP_PKEY *pkey = NULL, *param;

/* Assumes that param is already set up. */
ctx = EVP_PKEY_CTX_new(param, NULL);
if (!ctx)
        /* Error occurred */
if (EVP_PKEY_keygen_init(ctx) <= 0)
        /* Error */

/* Generate key */
if (EVP_PKEY_keygen(ctx, &pkey) <= 0)
        /* Error */

Example of generation callback for OpenSSL public key implementations:

/* Application data is a BIO to output status to */

EVP_PKEY_CTX_set_app_data(ctx, status_bio);

static int
genpkey_cb(EVP_PKEY_CTX *ctx)
{
        char c = '*';
        BIO *b = EVP_PKEY_CTX_get_app_data(ctx);
        int p;

        p = EVP_PKEY_CTX_get_keygen_info(ctx, 0);
        if (p == 0)
                c = '.';
        if (p == 1)
                c = '+';
        if (p == 2)
                c = '*';
        if (p == 3)
                c = '\n';
        BIO_write(b, &c, 1);
        (void)BIO_flush(b);
        return 1;
}

πŸ”₯ SEE ALSO πŸ”₯

EVP_PKEY_CTX_new(3), EVP_PKEY_decrypt(3), EVP_PKEY_derive(3), EVP_PKEY_encrypt(3), EVP_PKEY_sign(3), EVP_PKEY_verify(3), EVP_PKEY_verify_recover(3), X25519(3)

Go read the extended universe, bestie πŸ“š

πŸ‘‘ HISTORY πŸ‘‘

These functions first appeared in OpenSSL 1.0.0 and have been available since OpenBSD 4.9. Legacy icons, honestly.


and that's the page!! mwah πŸ’‹ This cutie came to you from the Debian edition of the manual, dated December 6, 2024. Go generate something gorgeous. πŸ“βœ¨

πŸ“¦ where this page comes from