EVP_SKEY(3ssl)

πŸ“¦ version 4.1.0, in nixos 26.05, nixpkgs unstable

πŸ’… EVP_SKEY(3ssl) β€” opaque symmetric key allocation and handling, bestie edition

okay so this is the OpenSSL page for EVP_SKEY and its whole friend group, and honestly? it's giving "keys but make them mysterious." let's get into it 🫢


✨ NAME ✨

EVP_SKEY, EVP_SKEY_generate, EVP_SKEY_import, EVP_SKEY_import_raw_key, EVP_SKEY_import_SKEYMGMT, EVP_SKEY_up_ref, EVP_SKEY_export, EVP_SKEY_get0_raw_key, EVP_SKEY_get0_key_id, EVP_SKEY_get0_skeymgmt_name, EVP_SKEY_get0_provider_name, EVP_SKEY_free, EVP_SKEY_is_a, EVP_SKEY_to_provider, EVP_SKEY_get0_local_keyid, EVP_SKEY_get0_algorithm_id β€” opaque symmetric key allocation and handling functions πŸ”‘


🌸 SYNOPSIS 🌸

#include <openssl/evp.h>

typedef evp_skey_st EVP_SKEY;

EVP_SKEY *EVP_SKEY_generate(OSSL_LIB_CTX *libctx, const char *skeymgmtname,
                            const char *propquery, const OSSL_PARAM *params);
EVP_SKEY *EVP_SKEY_import(OSSL_LIB_CTX *libctx, const char *skeymgmtname,
                          const char *propquery,
                          int selection, const OSSL_PARAM *params);
EVP_SKEY *EVP_SKEY_import_raw_key(OSSL_LIB_CTX *libctx, const char *skeymgmtname,
                                  unsigned char *key, size_t len,
                                  const char *propquery);
EVP_SKEY *EVP_SKEY_import_SKEYMGMT(OSSL_LIB_CTX *libctx, EVP_SKEYMGMT *skeymgmt,
                                   int selection, const OSSL_PARAM *params);
int EVP_SKEY_export(const EVP_SKEY *skey, int selection,
                    OSSL_CALLBACK *export_cb, void *export_cbarg);
int EVP_SKEY_get0_raw_key(const EVP_SKEY *skey, const unsigned char **key,
                         size_t *len);
const char *EVP_SKEY_get0_key_id(const EVP_SKEY *skey);

const char *EVP_SKEY_get0_skeymgmt_name(const EVP_SKEY *skey);
const char *EVP_SKEY_get0_provider_name(const EVP_SKEY *skey);

int EVP_SKEY_up_ref(EVP_SKEY *key);
void EVP_SKEY_free(EVP_SKEY *key);
int EVP_SKEY_is_a(const EVP_SKEY *skey, const char *name);
EVP_SKEY *EVP_SKEY_to_provider(EVP_SKEY *skey, OSSL_LIB_CTX *libctx,
                               OSSL_PROVIDER *prov, const char *propquery);

int EVP_SKEY_get0_local_keyid(const EVP_SKEY *skey,
                              const unsigned char **id, size_t *len);
int EVP_SKEY_get0_algorithm_id(const EVP_SKEY *skey,
                                const unsigned char **oid, size_t *oid_len,
                                const unsigned char **params,
                                size_t *params_len);

πŸ¦‹ DESCRIPTION πŸ¦‹

so EVP_SKEY is a generic structure that holds symmetric keys as opaque objects. like, you can hold it, you can pass it around, you just can't peek inside it directly πŸ‘€. the actual keys inside are usually called the "internal key", and providers handle them using EVP_SKEYMGMT(3).

conceptually? an EVP_SKEY internal key may hold a symmetric key, and along with that, key parameters if the key type requires them. so it's a key plus its little accessories πŸ’…

EVP_SKEY_generate() creates a new EVP_SKEY object and initializes it according to the params argument. brand new, fresh out the box ✨

EVP_SKEY_import() allocates an empty EVP_SKEY structure β€” this is what OpenSSL uses to store symmetric keys β€” assigns the EVP_SKEYMGMT object associated with the key, and initializes the object from the params argument.

EVP_SKEY_import_raw_key() is the little helper that creates an EVP_SKEY object containing the raw byte representation of the symmetric keys from the buffer key having length len. the skeymgmtname defines the name of the target EVP_SKEYMGMT for this newly created key πŸŽ€

EVP_SKEY_import_SKEYMGMT() is a helper that creates an EVP_SKEY object containing the representation of the symmetric keys specific to that particular EVP_SKEYMGMT.

EVP_SKEY_export() extracts values from a key skey using the selection. selection is described below (spoiler: it's the Selections section πŸ’€). it uses a callback export_cb that gets passed the value of export_cbarg. see openssl-core.h(7) for more info about the callback. note: the OSSL_PARAM(3) array that is passed to the callback is not persistent after the callback returns β€” so don't go keeping a pointer to it, bestie, it will not be there 😭

EVP_SKEY_get0_raw_key() returns a pointer to the raw key bytes at the passed address and sets the key len. the returned address is managed by the internal key management and shouldn't be freed explicitly β€” hands off 🫢. this operation can fail when the underlying key management doesn't support export of the secret key.

EVP_SKEY_get0_key_id() returns a NUL-terminated string giving some human-readable identifier of the key β€” if the underlying key management provides one. the pointer becomes invalid after freeing the EVP_SKEY object, so like… use it before it's gone πŸ™ˆ

EVP_SKEY_get0_skeymgmt_name() and EVP_SKEY_get0_provider_name() return the names of the associated EVP_SKEYMGMT object and its provider, correspondingly.

EVP_SKEY_up_ref() increments the reference count of key.

EVP_SKEY_free() decrements the reference count of key and, if the reference count is zero, frees it. if key is NULL, nothing is done. no drama, no crash πŸ’€

EVP_SKEY_is_a() checks if the key type of skey is name.

EVP_SKEY_to_provider() simplifies the task of importing a skey into a different provider identified by prov. if prov is NULL, the default provider for the key type identified via skey is used. convenient ✨

πŸŽ€ Metadata πŸŽ€

an EVP_SKEY object can carry optional metadata alongside the cryptographic key material. this metadata is managed by the provider through the EVP_SKEYMGMT import/export mechanism and stored in the provider-side key data.

the friendly name (alias) is accessible via EVP_SKEY_get0_key_id(), which dispatches to the provider's OSSL_FUNC_skeymgmt_get_key_id function. the built-in providers return the value of OSSL_SKEY_PARAM_ALIAS if it was set during import.

EVP_SKEY_get0_local_keyid() retrieves the local key identifier from skey. on success, *id is set to a pointer to the identifier bytes and *len is set to the length. the returned pointer is valid for the lifetime of skey. returns 1 on success, 0 on error.

EVP_SKEY_get0_algorithm_id() retrieves the algorithm identifier from skey. it can return both the DER-encoded algorithm OID (via oid and oid_len) and the DER-encoded algorithm parameters (via params and params_len). either output pair may be NULL if the caller doesn't need that part. the returned pointers are valid for the lifetime of skey. returns 1 on success, 0 on error.

these metadata fields are populated on obtaining the key object (e.g. when parsing PKCS#12 files). for PKCS#12 files the friendly name and local key ID correspond to PKCS#12 bag attributes (NID_friendlyName and NID_localKeyID), while the algorithm OID and parameters are extracted from the PKCS8 AlgorithmIdentifier.

the implementation is in general provider-dependent. if the corresponding callback is not implemented for the EVP_SKEYMGMT, 0 is returned. however β€” and this is lowkey important β€” as metadata is completely optional, the success doesn't indicate that the data is available. so like, don't read too much into a 1 πŸ‘€

πŸ’œ Selections πŸ’œ

you can use these constants for selection:

  • OSSL_SKEYMGMT_SELECT_SECRET_KEY β€” only the raw key representation will be selected. just the key, ma'am 🫑
  • OSSL_SKEYMGMT_SELECT_PARAMETERS β€” only the key parameters will be selected. this includes optional key parameters.
  • OSSL_SKEYMGMT_SELECT_ALL β€” all parameters will be selected. the whole menu, no skips πŸ”₯

πŸ‘‘ NOTES πŸ‘‘

the EVP_SKEY structure is used by various OpenSSL functions that require a general symmetric key without reference to any particular algorithm. it's the main character that works with everyone 🌈

the EVP_SKEY_to_provider() function will fail and return NULL if the origin key skey cannot be exported from its provider. harsh but fair.


⭐ RETURN VALUES ⭐

  • EVP_SKEY_generate(), EVP_SKEY_import(), EVP_SKEY_import_raw_key(), and EVP_SKEY_import_SKEYMGMT() return either the newly allocated EVP_SKEY structure or NULL if an error occurred.
  • EVP_SKEY_get0_key_id() returns either a valid pointer or NULL.
  • EVP_SKEY_up_ref() returns 1 for success and 0 on failure.
  • EVP_SKEY_export() and EVP_SKEY_get0_raw_key() return 1 for success and 0 on failure.
  • EVP_SKEY_get0_skeymgmt_name() and EVP_SKEY_get0_provider_name() return the names of the associated EVP_SKEYMGMT object and its provider, correspondingly.
  • EVP_SKEY_is_a() returns 1 if skey has the key type name, otherwise 0.
  • EVP_SKEY_to_provider() returns a new EVP_SKEY suitable for operations with the prov provider, or NULL in case of failure.
  • EVP_SKEY_get0_local_keyid() and EVP_SKEY_get0_algorithm_id() return 1 on success or 0 on error.

πŸ”₯ SEE ALSO πŸ”₯

EVP_SKEYMGMT(3), provider(7), OSSL_PARAM(3) β€” go read these next, bestie, they're the supporting cast 🫢


🌈 HISTORY 🌈

the EVP_SKEY API and the functions EVP_SKEY_export(), EVP_SKEY_free(), EVP_SKEY_get0_raw_key(), EVP_SKEY_import(), EVP_SKEY_import_raw_key(), EVP_SKEY_up_ref(), EVP_SKEY_generate(), EVP_SKEY_get0_key_id(), EVP_SKEY_get0_provider_name(), EVP_SKEY_get0_skeymgmt_name(), EVP_SKEY_is_a(), EVP_SKEY_to_provider() were introduced in OpenSSL 3.5. a whole era πŸ’…

the EVP_SKEY_import_SKEYMGMT() function was introduced in OpenSSL 4.0. glow-up ✨

the EVP_SKEY_get0_local_keyid() and EVP_SKEY_get0_algorithm_id() functions were added in OpenSSL 4.1. the newest icons on the block πŸŽ€


Copyright 2025-2026 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 <https://www.openssl.org/source/license.html>.


and that's the page!! mwah πŸ’‹ this was EVP_SKEY(3ssl) from 4.1.0, dated 2026-10-23 β€” go forth and manage those opaque symmetric keys, bestie, you've got this πŸ¦‹πŸ’œ

πŸ“¦ where this page comes from