PROVIDER-ASYM_CIPHER(7SSL)

✨ NAME ✨

provider-asym_cipher β€” bestie, this is the whole asym_cipher library <-> provider functions situation πŸ’… the glue that lets OpenSSL's asymmetric ciphers (think RSA encryption/decryption vibes) get dispatched between the library and a provider.

Okay so real talk, this page is provider-asym_cipher(7SSL) and it's giving very core-API energy. Like, if you're writing a provider and you wanna offer asymmetric encryption, this is your girl. Let's get into it 🫢

πŸ¦‹ SYNOPSIS πŸ¦‹

#include <openssl/core_dispatch.h>
#include <openssl/core_names.h>

/*
 * None of these are actual functions, but are displayed like this for
 * the function signatures for functions that are offered as function
 * pointers in OSSL_DISPATCH arrays.
 */

/* Context management */
void *OSSL_FUNC_asym_cipher_newctx(void *provctx);
void OSSL_FUNC_asym_cipher_freectx(void *ctx);
void *OSSL_FUNC_asym_cipher_dupctx(void *ctx);

/* Encryption */
int OSSL_FUNC_asym_cipher_encrypt_init(void *ctx, void *provkey,
                                       const OSSL_PARAM params[]);
int OSSL_FUNC_asym_cipher_encrypt(void *ctx, unsigned char *out, size_t *outlen,
                                  size_t outsize, const unsigned char *in,
                                  size_t inlen);

/* Decryption */
int OSSL_FUNC_asym_cipher_decrypt_init(void *ctx, void *provkey,
                                       const OSSL_PARAM params[]);
int OSSL_FUNC_asym_cipher_decrypt(void *ctx, unsigned char *out, size_t *outlen,
                                  size_t outsize, const unsigned char *in,
                                  size_t inlen);

/* Asymmetric Cipher parameters */
int OSSL_FUNC_asym_cipher_get_ctx_params(void *ctx, OSSL_PARAM params[]);
const OSSL_PARAM *OSSL_FUNC_asym_cipher_gettable_ctx_params(void *ctx, void *provctx);
int OSSL_FUNC_asym_cipher_set_ctx_params(void *ctx, const OSSL_PARAM params[]);
const OSSL_PARAM *OSSL_FUNC_asym_cipher_settable_ctx_params(void *ctx, void *provctx);

⚠️ a lil PSA before u try to grep for these in the source: none of these are actual functions. Fr fr, not one. They get displayed like this purely so you can read the function signatures for the functions that are offered as function pointers inside OSSL_DISPATCH arrays. It's a vibe, not a callable. If you try to link against them you will simply be humbled 😭

And that's the whole SYNOPSIS, queen. The juicy stuff β€” allllll the DESCRIPTION lore β€” is coming in the next part, so stay tuned πŸ’–πŸŽ€


✨ DESCRIPTION ✨

okay so real talk: this page is mainly for provider authors, bestie. like, the people writing providers. if that's not you, go peek at provider(7) first for the bigger picture. πŸ’–

The asymmetric cipher operation β€” that's OSSL_OP_ASYM_CIPHER β€” is the thing that lets providers implement asymmetric cipher algorithms and hand them over to applications through the API functions EVP_PKEY_encrypt(3), EVP_PKEY_decrypt(3) and other related functions). ✨

Every single "function" we gossip about down here gets passed as a function pointer back and forth between libcrypto and the provider inside OSSL_DISPATCH(3) arrays, which ride along in OSSL_ALGORITHM(3) arrays that get returned by the provider's provider_query_operation() function (check out "Provider Functions" over in provider-base(7)). πŸŽ€

So check it β€” all of these "functions" have a matching function type definition named OSSL_FUNC_{name}_fn, plus a little helper function that fishes the function pointer out of an OSSL_DISPATCH(3) element, named OSSL_FUNC_{name}. For example, the "function" OSSL_FUNC_asym_cipher_newctx() has these two besties:

typedef void *(OSSL_FUNC_asym_cipher_newctx_fn)(void *provctx);
static ossl_inline OSSL_FUNC_asym_cipher_newctx_fn
    OSSL_FUNC_asym_cipher_newctx(const OSSL_DISPATCH *opf);

The OSSL_DISPATCH(3) arrays are indexed by numbers given to us as macros in openssl-core_dispatch.h(7), and they line up like this, no cap:

OSSL_FUNC_asym_cipher_newctx               OSSL_FUNC_ASYM_CIPHER_NEWCTX
OSSL_FUNC_asym_cipher_freectx              OSSL_FUNC_ASYM_CIPHER_FREECTX
OSSL_FUNC_asym_cipher_dupctx               OSSL_FUNC_ASYM_CIPHER_DUPCTX

OSSL_FUNC_asym_cipher_encrypt_init         OSSL_FUNC_ASYM_CIPHER_ENCRYPT_INIT
OSSL_FUNC_asym_cipher_encrypt              OSSL_FUNC_ASYM_CIPHER_ENCRYPT

OSSL_FUNC_asym_cipher_decrypt_init         OSSL_FUNC_ASYM_CIPHER_DECRYPT_INIT
OSSL_FUNC_asym_cipher_decrypt              OSSL_FUNC_ASYM_CIPHER_DECRYPT

OSSL_FUNC_asym_cipher_get_ctx_params       OSSL_FUNC_ASYM_CIPHER_GET_CTX_PARAMS
OSSL_FUNC_asym_cipher_gettable_ctx_params  OSSL_FUNC_ASYM_CIPHER_GETTABLE_CTX_PARAMS
OSSL_FUNC_asym_cipher_set_ctx_params       OSSL_FUNC_ASYM_CIPHER_SET_CTX_PARAMS
OSSL_FUNC_asym_cipher_settable_ctx_params  OSSL_FUNC_ASYM_CIPHER_SETTABLE_CTX_PARAMS

An asymmetric cipher algorithm implementation does not have to implement every single one of these, btw. But to be a consistent set of functions, a provider must implement OSSL_FUNC_asym_cipher_newctx and OSSL_FUNC_asym_cipher_freectx. It also has to implement either both of OSSL_FUNC_asym_cipher_encrypt_init and OSSL_FUNC_asym_cipher_encrypt, or both of OSSL_FUNC_asym_cipher_decrypt_init and OSSL_FUNC_asym_cipher_decrypt. OSSL_FUNC_asym_cipher_get_ctx_params is optional, but the second it shows up, OSSL_FUNC_asym_cipher_gettable_ctx_params has to show up too β€” they're a package deal. Same energy with OSSL_FUNC_asym_cipher_set_ctx_params: optional, but if it's there, OSSL_FUNC_asym_cipher_settable_ctx_params must be there too. 🫢

And an asymmetric cipher algorithm also has to implement some mechanism for generating, loading or importing keys via the key management (OSSL_OP_KEYMGMT) operation. Go read provider-keymgmt(7) for the tea. πŸ¦‹


🌸 Context Management Functions 🌸

OSSL_FUNC_asym_cipher_newctx() β€” this one should create and return a pointer to a provider-side structure that holds all the context info during an asymmetric cipher operation. That pointer gets passed back into a bunch of the other asymmetric cipher operation function calls, so it's kind of the main character here. πŸ’… The parameter provctx is the provider context that got generated during provider initialisation (peep provider(7)).

OSSL_FUNC_asym_cipher_freectx() gets handed a pointer to the provider-side asymmetric cipher context in the ctx parameter. This function should free up any resources hanging out with that context. bye bestie πŸ‘‹

OSSL_FUNC_asym_cipher_dupctx() should duplicate the provider-side asymmetric cipher context sitting in ctx and return the duplicate copy. twin energy πŸ”₯

πŸ” Encryption Functions πŸ”

OSSL_FUNC_asym_cipher_encrypt_init() initialises a context for an asymmetric encryption, given a provider-side asymmetric cipher context in ctx and a pointer to a provider key object in provkey. The params, if they're not NULL, should be set on the context in a way that's basically the same as using OSSL_FUNC_asym_cipher_set_ctx_params(). That key object should have already been generated, loaded or imported into the provider using the key management (OSSL_OP_KEYMGMT) operation (again: provider-keymgmt(7)). ✨

OSSL_FUNC_asym_cipher_encrypt() does the actual encrypting. A previously initialised asymmetric cipher context comes in through ctx. The data to be encrypted is pointed to by the in parameter, and it's inlen bytes long. Unless out is NULL, the encrypted data should be written to where out points, and it should not exceed outsize bytes in length. The length of the encrypted data should be written to *outlen. And if out is NULL, then instead you write the maximum possible length of the encrypted data to *outlen. no pressure πŸ’€

πŸ”“ Decryption Functions πŸ”“

OSSL_FUNC_asym_cipher_decrypt_init() initialises a context for an asymmetric decryption, given a provider-side asymmetric cipher context in ctx and a pointer to a provider key object in provkey. The params, if not NULL, should be set on the context in a manner similar to using OSSL_FUNC_asym_cipher_set_ctx_params(). That key object should have previously been generated, loaded or imported into the provider using the key management (OSSL_OP_KEYMGMT) operation (yes, provider-keymgmt(7), you know the drill). πŸ’œ

OSSL_FUNC_asym_cipher_decrypt() performs the actual decryption. A previously initialised asymmetric cipher context comes in via ctx. The data to be decrypted is pointed to by in, which is inlen bytes long. Unless out is NULL, the decrypted data should be written to the location out points to, and it shouldn't exceed outsize bytes in length. The length of the decrypted data should be written to *outlen. If out is NULL then the maximum length of the decrypted data should be written to *outlen. iconique 🌈

πŸŽ€ Asymmetric Cipher Parameters πŸŽ€

Hit up OSSL_PARAM(3) for all the deets on the parameters structure that OSSL_FUNC_asym_cipher_get_ctx_params() and OSSL_FUNC_asym_cipher_set_ctx_params() work with. πŸ“š

OSSL_FUNC_asym_cipher_get_ctx_params() gets the asymmetric cipher parameters associated with the given provider-side asymmetric cipher context ctx and stores them in params. Passing NULL for params should return true.

OSSL_FUNC_asym_cipher_set_ctx_params() sets the asymmetric cipher parameters associated with the given provider-side asymmetric cipher context ctx to params. Any parameter settings are additional to whatever was previously set β€” nothing gets wiped, bestie. Passing NULL for params should return true.

So these are the parameters currently recognised by the built-in asymmetric cipher algorithms. Heads up tho: not all parameters are relevant to, or understood by, all asymmetric cipher algorithms. πŸ™ˆ

  • "pad-mode" (OSSL_ASYM_CIPHER_PARAM_PAD_MODE) <UTF8 string> OR <integer> β€” the type of padding to be used. How you interpret this value depends entirely on which algorithm is in play.
  • "digest" (OSSL_ASYM_CIPHER_PARAM_OAEP_DIGEST) <UTF8 string> β€” gets or sets the name of the OAEP digest algorithm used when OAEP padding is in use.
  • "digest" (OSSL_ASYM_CIPHER_PARAM_DIGEST) <UTF8 string> β€” gets or sets the name of the digest algorithm used by the algorithm (where applicable).
  • "digest-props" (OSSL_ASYM_CIPHER_PARAM_OAEP_DIGEST_PROPS) <UTF8 string> β€” gets or sets the properties to use when fetching the OAEP digest algorithm.
  • "digest-props" (OSSL_ASYM_CIPHER_PARAM_DIGEST_PROPS) <UTF8 string> β€” gets or sets the properties to use when fetching the cipher digest algorithm.
  • "mgf1-digest" (OSSL_ASYM_CIPHER_PARAM_MGF1_DIGEST) <UTF8 string> β€” gets or sets the name of the MGF1 digest algorithm used when OAEP or PSS padding is in use.
  • "mgf1-digest-props" (OSSL_ASYM_CIPHER_PARAM_MGF1_DIGEST_PROPS) <UTF8 string> β€” gets or sets the properties to use when fetching the MGF1 digest algorithm.
  • "oaep-label" (OSSL_ASYM_CIPHER_PARAM_OAEP_LABEL) <octet string ptr> β€” gets the OAEP label used when OAEP padding is in use.
  • "oaep-label" (OSSL_ASYM_CIPHER_PARAM_OAEP_LABEL) <octet string> β€” sets the OAEP label used when OAEP padding is in use.
  • "tls-client-version" (OSSL_ASYM_CIPHER_PARAM_TLS_CLIENT_VERSION) <unsigned integer> β€” the TLS protocol version that the client requested first.
  • "tls-negotiated-version" (OSSL_ASYM_CIPHER_PARAM_TLS_CLIENT_VERSION) <unsigned integer> β€” the negotiated TLS protocol version.
  • "implicit-rejection" (OSSL_ASYM_CIPHER_PARAM_IMPLICIT_REJECTION) <unsigned integer> β€” gets or sets the use of the implicit rejection mechanism for RSA PKCS#1 v1.5 decryption. When it's set (a non zero value), the decryption API will return a deterministically random value if the PKCS#1 v1.5 padding check fails. This makes exploitation of the Bleichenbacher significantly harder, even if the code using the RSA decryption API is not implemented in a side-channel free manner. It's set by default in OpenSSL providers. πŸ›‘οΈ

The OpenSSL FIPS provider also supports these ones:

  • "fips-indicator" (OSSL_ASYM_CIPHER_PARAM_FIPS_APPROVED_INDICATOR) <integer> β€” a getter that returns 1 if the operation is FIPS approved, or 0 otherwise. You can use it after calling either OSSL_FUNC_asym_cipher_encrypt() or OSSL_FUNC_asym_cipher_decrypt(). It may return 0 if "key-check" is set to 0.
  • "key-check" (OSSL_ASYM_CIPHER_PARAM_FIPS_KEY_CHECK) <integer> β€” if it's required, this parameter should be set using either OSSL_FUNC_asym_cipher_encrypt_init() or OSSL_FUNC_asym_cipher_decrypt_init(). The default value of 1 causes an error during the init if the key is not FIPS approved (e.g. the key has a security strength of less than 112 bits). Setting this to 0 will ignore the error and set the approved "fips-indicator" to 0.
⚠️ Setting "key-check" to 0 breaks FIPS compliance if it causes the approved "fips-indicator" to return 0. so like, don't do that if you care about being compliant. πŸ’€

And finally β€” OSSL_FUNC_asym_cipher_gettable_ctx_params() and OSSL_FUNC_asym_cipher_settable_ctx_params() get a constant OSSL_PARAM(3) array that describes the gettable and settable parameters, i.e. the parameters that can be used with OSSL_FUNC_asym_cipherget_ctx_params() and OSSL_FUNC_asym_cipher_set_ctx_params() respectively. 🧚


✨ RETURN VALUES ✨

OSSL_FUNC_asym_cipher_newctx() and OSSL_FUNC_asym_cipher_dupctx() should return the newly created provider-side asymmetric cipher context, or NULL if it all went wrong. 😭

Every other function should return 1 for success or 0 on error. simple as that, periodt. πŸ’…

🌈 SEE ALSO 🌈

⭐ HISTORY ⭐

The provider ASYM_CIPHER interface was introduced in OpenSSL 3.0. The Asymmetric Cipher Parameters "fips-indicator" and "key-check" were added in OpenSSL 3.4. πŸŽ‰

okay besties, legal moment but make it cute ✨

Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved.

fr fr, that's the whole crew β€” every author, every contributor, the entire OpenSSL Project hive mind πŸ’–


πŸŽ€ License vibes πŸŽ€

Licensed under the Apache License 2.0 (the "License"). And no cap β€” you may not use this file except in compliance with the License. Like, actually. It's not a suggestion, it's the rules, bestie πŸ’…

To snag a copy of the License, you literally just:

that's it, that's the whole requirement πŸ¦‹


🌸 the sign-off 🌸

this iconic lil page is from OpenSSL version 4.0.3, dated 2026-09-29, and it lives in section PROVIDER-ASYM_CIPHER(7SSL) 🫢

like, imagine being a manpage with main character energy β€” couldn't be anyone else πŸ’œ

anyway, go forth and cipher asymmetrically, bestie. you got this πŸ’–βœ¨πŸ‘‘

πŸ“¦ where this page comes from