Commit 1935d215b5 for openssl.org

commit 1935d215b5c6bc8619342e6271cfd52837517112
Author: Dmitry Belyavskiy <beldmit@gmail.com>
Date:   Wed Sep 2 14:38:46 2026 +0200

    Add metadata support to EVP_SKEY objects

    Assisted-by: Claude Opus 4.6 <noreply@anthropic.com>

    Reviewed-by: Mounir Idrassi <mounir.idrassi@idrix.fr>
    Reviewed-by: Simo Sorce <simo@redhat.com>
    MergeDate: Sat Sep  5 17:06:55 2026
    (Merged from https://github.com/openssl/openssl/pull/32644)

diff --git a/CHANGES.md b/CHANGES.md
index c428b12302..be18343f0b 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -67,6 +67,10 @@ OpenSSL 4.1

    *Daniel Kubec and Viktor Dukhovni*

+ * Implement extended support of metadata for symmetric key objects (EVP_SKEY).
+
+   *Dmitry Belyavskiy*
+
  * Declare support for AArch64 Guarded Control Stack (GCS) in assembly code.

    When building with compilers that support GCS (Clang 18+, GCC 15+),
diff --git a/crypto/evp/evp_local.h b/crypto/evp/evp_local.h
index 1f41cfe644..749bc09f55 100644
--- a/crypto/evp/evp_local.h
+++ b/crypto/evp/evp_local.h
@@ -232,6 +232,10 @@ struct evp_skeymgmt_st {
     /* Key identifier */
     OSSL_FUNC_skeymgmt_get_key_id_fn *get_key_id;

+    /* Key metadata accessors */
+    OSSL_FUNC_skeymgmt_get_local_keyid_fn *get_local_keyid;
+    OSSL_FUNC_skeymgmt_get_algorithm_id_fn *get_algorithm_id;
+
     /* destructor */
     OSSL_FUNC_skeymgmt_free_fn *free;
 } /* EVP_SKEYMGMT */;
diff --git a/crypto/evp/s_lib.c b/crypto/evp/s_lib.c
index 3f76136324..3778d68503 100644
--- a/crypto/evp/s_lib.c
+++ b/crypto/evp/s_lib.c
@@ -340,3 +340,49 @@ err:
     EVP_SKEY_free(ret);
     return NULL;
 }
+
+int EVP_SKEY_get0_local_keyid(const EVP_SKEY *skey,
+    const unsigned char **id, size_t *len)
+{
+    if (skey == NULL || id == NULL || len == NULL) {
+        ERR_raise(ERR_LIB_EVP, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+
+    if (skey->skeymgmt->get_local_keyid == NULL)
+        return 0;
+
+    return skey->skeymgmt->get_local_keyid(skey->keydata, id, 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)
+{
+    int ret_oid = 0, ret_params = 0;
+
+    if (skey == NULL) {
+        ERR_raise(ERR_LIB_EVP, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+
+    if (skey->skeymgmt->get_algorithm_id == NULL)
+        return 0;
+
+    if (oid != NULL && oid_len != NULL)
+        ret_oid = 1;
+    if (params != NULL && params_len != NULL)
+        ret_params = 1;
+
+    if (ret_oid == 0 && ret_params == 0)
+        return 0;
+
+    if (ret_oid == 0 && (oid != NULL || oid_len != NULL))
+        return 0;
+
+    if (ret_params == 0 && (params != NULL || params_len != NULL))
+        return 0;
+
+    return skey->skeymgmt->get_algorithm_id(skey->keydata,
+        oid, oid_len, params, params_len);
+}
diff --git a/crypto/evp/skeymgmt_meth.c b/crypto/evp/skeymgmt_meth.c
index dbc14c0e0d..a44498c214 100644
--- a/crypto/evp/skeymgmt_meth.c
+++ b/crypto/evp/skeymgmt_meth.c
@@ -100,6 +100,14 @@ static void *skeymgmt_from_algorithm(int name_id,
             if (skeymgmt->get_key_id == NULL)
                 skeymgmt->get_key_id = OSSL_FUNC_skeymgmt_get_key_id(fns);
             break;
+        case OSSL_FUNC_SKEYMGMT_GET_LOCAL_KEYID:
+            if (skeymgmt->get_local_keyid == NULL)
+                skeymgmt->get_local_keyid = OSSL_FUNC_skeymgmt_get_local_keyid(fns);
+            break;
+        case OSSL_FUNC_SKEYMGMT_GET_ALGORITHM_ID:
+            if (skeymgmt->get_algorithm_id == NULL)
+                skeymgmt->get_algorithm_id = OSSL_FUNC_skeymgmt_get_algorithm_id(fns);
+            break;
         case OSSL_FUNC_SKEYMGMT_IMP_SETTABLE_PARAMS:
             if (skeymgmt->imp_params == NULL)
                 skeymgmt->imp_params = OSSL_FUNC_skeymgmt_imp_settable_params(fns);
diff --git a/doc/designs/evp_skey_metadata.md b/doc/designs/evp_skey_metadata.md
new file mode 100644
index 0000000000..fa8e09470b
--- /dev/null
+++ b/doc/designs/evp_skey_metadata.md
@@ -0,0 +1,133 @@
+EVP_SKEY metadata support for PKCS#12 symmetric keys
+====================================================
+
+Problem
+-------
+
+When parsing PKCS#12 files, the resulting object should be created with both
+raw key bytes and other attributes (the friendly name, local key ID, original
+AlgorithmIdentifier with parameters etc).
+
+We can store metadata in the provider-side `PROV_SKEY` structure and manage it
+through the `EVP_SKEYMGMT` import/export mechanism. This keeps `evp_skey_st`
+opaque to metadata details and lets providers handle metadata naturally through
+`OSSL_PARAM`.
+
+The alias (friendly name) is returned through the existing `EVP_SKEY_get0_key_id`
+API, which dispatches to `skeymgmt->get_key_id`.
+
+Binary metadata (local key ID, algorithm parameters) uses byte-pointer + length
+pairs.
+
+OSSL_PARAM names for metadata
+------------------------------
+
+New parameter name constants in `include/openssl/core_names.h`:
+
+```c
+#define OSSL_SKEY_PARAM_ALIAS            "skey-alias"
+#define OSSL_SKEY_PARAM_LOCAL_KEYID      "skey-local-keyid"
+#define OSSL_SKEY_PARAM_ALGORITHM_OID    "skey-algorithm-oid"
+#define OSSL_SKEY_PARAM_ALGORITHM_PARAMS "skey-algorithm-params"
+```
+
+- `OSSL_SKEY_PARAM_ALIAS` — UTF-8 string, the friendly name / key identifier.
+  Used as the return value from `skeymgmt->get_key_id`.
+- `OSSL_SKEY_PARAM_LOCAL_KEYID` — octet string, the PKCS#12 local key ID.
+- `OSSL_SKEY_PARAM_ALGORITHM_OID` — octet string, the DER-encoded algorithm
+  OID from the AlgorithmIdentifier.
+- `OSSL_SKEY_PARAM_ALGORITHM_PARAMS` — octet string, the DER-encoded algorithm
+  parameters from the AlgorithmIdentifier.
+
+PROV_SKEY changes
+-----------------
+
+Extend `struct prov_skey_st` in `include/internal/skey.h`:
+
+```c
+struct prov_skey_st {
+    OSSL_LIB_CTX *libctx;
+    int type;
+    unsigned char *data;
+    size_t length;
+
+    /* Metadata — set during import, returned during export / get_key_id */
+    char *alias;                    /* friendly name, may be NULL */
+    unsigned char *local_keyid;     /* local key ID, may be NULL */
+    size_t local_keyid_len;
+    unsigned char *algorithm_oid;   /* DER-encoded algorithm OID, may be NULL */
+    size_t algorithm_oid_len;
+    unsigned char *algorithm_params; /* DER-encoded alg params, may be NULL */
+    size_t algorithm_params_len;
+};
+```
+
+All metadata fields are optional (NULL when not provided). `generic_free()`
+must free them with `OPENSSL_free()`.
+
+EVP_SKEYMGMT implementation changes
+------------------------------------
+
+### generic skeymgmt
+
+- **Import**: decode new `OSSL_SKEY_PARAM_*` parameters from the import params
+  and store them in the `PROV_SKEY` fields.
+- **Export**: include metadata params alongside `OSSL_SKEY_PARAM_RAW_BYTES`
+  when the corresponding fields are non-NULL.
+- **get_key_id**: implement `OSSL_FUNC_SKEYMGMT_GET_KEY_ID` — return
+  `prov_skey->alias`. This makes `EVP_SKEY_get0_key_id()` return the
+  friendly name.
+- **get_local_keyid**: implement `OSSL_FUNC_SKEYMGMT_GET_LOCAL_KEYID` —
+  return `prov_skey->local_keyid` and its length. This makes
+  `EVP_SKEY_get0_local_keyid()` work via dispatch.
+- **get_algorithm_id**: implement `OSSL_FUNC_SKEYMGMT_GET_ALGORITHM_ID` —
+  return DER-encoded OID and parameters from `prov_skey`. This makes
+  `EVP_SKEY_get0_algorithm_id()` work via dispatch.
+- **Import settable params**: update `generic_skey_import_list` to include
+  the new params.
+- **free**: free all metadata fields.
+
+### AES skeymgmt
+
+Inherits generic import/export/free for metadata handling. No AES-specific
+metadata logic needed — the base `generic_import` already stores the fields.
+
+EVP_SKEY metadata accessors
+----------------------------
+
+We implement the following accessors:
+
+- **Alias**: `EVP_SKEY_get0_key_id()` (existing API, no changes).
+  Returns `const char *` — the friendly name from the provider.
+
+- **Local key ID**: new accessor via export:
+
+  ```c
+  int EVP_SKEY_get0_local_keyid(const EVP_SKEY *skey,
+                                 const unsigned char **id, size_t *len);
+  ```
+
+  Returns 1 on success (with `*id` and `*len` set), 0 on error.
+
+- **Algorithm identifier**: new accessor that returns both the DER-encoded OID
+  and the DER-encoded parameters:
+
+  ```c
+  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);
+  ```
+
+  Returns 1 on success. Either output pointer may be NULL if the caller
+  doesn't need that part.
+
+These accessors use dedicated `OSSL_FUNC_SKEYMGMT_GET_LOCAL_KEYID` and
+`OSSL_FUNC_SKEYMGMT_GET_ALGORITHM_ID` dispatch functions, following the
+pattern of `EVP_SKEY_get0_key_id()`.
+
+The implementation is in general provider-dependent. If the corresponding
+callback is not implemented for the EVP_SKEYMGMT, 0 is returned. However, as
+metadata is completely optional, the success doesn't indicate that the data is
+available.
diff --git a/doc/man3/EVP_SKEY.pod b/doc/man3/EVP_SKEY.pod
index f45aac10c5..b9ee17d1da 100644
--- a/doc/man3/EVP_SKEY.pod
+++ b/doc/man3/EVP_SKEY.pod
@@ -5,7 +5,8 @@
 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_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

 =head1 SYNOPSIS
@@ -39,6 +40,12 @@ EVP_SKEY_get0_provider_name, EVP_SKEY_free, EVP_SKEY_is_a, EVP_SKEY_to_provider
  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);

 =head1 DESCRIPTION

@@ -95,6 +102,41 @@ EVP_SKEY_to_provider() simplifies the task of importing a I<skey> into a
 different provider identified by I<prov>. If I<prov> is NULL, the default
 provider for the key type identified via I<skey> is used.

+=head2 Metadata
+
+An B<EVP_SKEY> object can carry optional metadata alongside the cryptographic
+key material. This metadata is managed by the provider through the
+B<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 B<OSSL_FUNC_skeymgmt_get_key_id> function.
+The built-in providers return the value of B<OSSL_SKEY_PARAM_ALIAS> if it
+was set during import.
+
+EVP_SKEY_get0_local_keyid() retrieves the local key identifier from I<skey>.
+On success, I<*id> is set to a pointer to the identifier bytes and I<*len>
+is set to the length. The returned pointer is valid for the lifetime of
+I<skey>. Returns 1 on success, 0 on error.
+
+EVP_SKEY_get0_algorithm_id() retrieves the algorithm identifier from I<skey>.
+It can return both the DER-encoded algorithm OID (via I<oid> and I<oid_len>)
+and the DER-encoded algorithm parameters (via I<params> and I<params_len>).
+Either output pair may be NULL if the caller does not need that part.
+The returned pointers are valid for the lifetime of I<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 (B<NID_friendlyName> and
+B<NID_localKeyID>), while the algorithm OID and parameters are extracted from
+the PKCS8 B<AlgorithmIdentifier>.
+
+The implementation is in general provider-dependent. If the corresponding
+callback is not implemented for the EVP_SKEYMGMT, 0 is returned. However, as
+metadata is completely optional, the success doesn't indicate that the data is
+available.
+
 =head2 Selections

 The following constants can be used for I<selection>:
@@ -145,6 +187,9 @@ otherwise 0.
 EVP_SKEY_to_provider() returns a new B<EVP_SKEY> suitable for operations with
 the I<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.
+
 =head1 SEE ALSO

 L<EVP_SKEYMGMT(3)>, L<provider(7)>, L<OSSL_PARAM(3)>
@@ -160,6 +205,9 @@ were introduced in OpenSSL 3.5.

 The EVP_SKEY_import_SKEYMGMT() function was introduced in OpenSSL 4.0.

+The EVP_SKEY_get0_local_keyid() and EVP_SKEY_get0_algorithm_id()
+functions were added in OpenSSL 4.1.
+
 =head1 COPYRIGHT

 Copyright 2025-2026 The OpenSSL Project Authors. All Rights Reserved.
diff --git a/doc/man7/provider-skeymgmt.pod b/doc/man7/provider-skeymgmt.pod
index c788178cb1..1d92fc5cab 100644
--- a/doc/man7/provider-skeymgmt.pod
+++ b/doc/man7/provider-skeymgmt.pod
@@ -27,6 +27,14 @@ provider-skeymgmt - The SKEYMGMT library E<lt>-E<gt> provider functions
  const OSSL_PARAM *OSSL_FUNC_skeymgmt_gen_settable_params(void *provctx);
  const OSSL_PARAM *OSSL_FUNC_skeymgmt_imp_settable_params(void *provctx);
  const char *OSSL_FUNC_skeymgmt_get_key_id(void *keydata);
+ int OSSL_FUNC_skeymgmt_get_local_keyid(void *keydata,
+                                         const unsigned char **id,
+                                         size_t *len);
+ int OSSL_FUNC_skeymgmt_get_algorithm_id(void *keydata,
+                                          const unsigned char **oid,
+                                          size_t *oid_len,
+                                          const unsigned char **params,
+                                          size_t *params_len);

 =head1 DESCRIPTION

@@ -63,6 +71,8 @@ macros in L<openssl-core_dispatch.h(7)>, as follows:
  OSSL_FUNC_skeymgmt_generate             OSSL_FUNC_SKEYMGMT_GENERATE

  OSSL_FUNC_skeymgmt_get_key_id           OSSL_FUNC_SKEYMGMT_GET_KEY_ID
+ OSSL_FUNC_skeymgmt_get_local_keyid      OSSL_FUNC_SKEYMGMT_GET_LOCAL_KEYID
+ OSSL_FUNC_skeymgmt_get_algorithm_id     OSSL_FUNC_SKEYMGMT_GET_ALGORITHM_ID
  OSSL_FUNC_skeymgmt_imp_settable_params  OSSL_FUNC_SKEYMGMT_IMP_SETTABLE_PARAMS
  OSSL_FUNC_skeymgmt_gen_settable_params  OSSL_FUNC_SKEYMGMT_GEN_SETTABLE_PARAMS

@@ -146,7 +156,21 @@ particular key. The returned string will be freed by a call to EVP_SKEY_free()
 so callers need to copy it themselves if they want to preserve the value past
 the key lifetime.  The purpose of this function is providing a printable string
 that can help users to access the specific key.  The content of this string is
-provider-specific.
+provider-specific.  The built-in implementations return the value of
+B<OSSL_SKEY_PARAM_ALIAS> if it was set during import.
+
+OSSL_FUNC_skeymgmt_get_local_keyid() retrieves the local key ID from I<keydata>.
+On success, it sets I<*id> to point to the key ID bytes and I<*len> to their
+length, and returns 1 on success and 0 on error. As metadata is optional, the
+resulting value still can be NULL and 0 correspondingly.
+
+OSSL_FUNC_skeymgmt_get_algorithm_id() retrieves the algorithm identifier from
+I<keydata>.  On success, it sets I<*oid> and I<*oid_len> to point to the
+DER-encoded algorithm OID, and I<*params> and I<*params_len> to point to the
+DER-encoded algorithm parameters.  Either output pointer pair may be NULL if
+the caller does not need that part.  Returns 1 if the requested data is set
+successfully and 0 otherwise.  As metadata is optional, the resulting value
+still can be NULL and 0 correspondingly.

 =head2 Common Import and Export Parameters

@@ -157,14 +181,33 @@ skeymgmt algorithms are as follows:

 =over 4

-=item "raw-bytes" (B<SKEY_PARAM_RAW_BYTES>) <octet string>
+=item "raw-bytes" (B<OSSL_SKEY_PARAM_RAW_BYTES>) <octet string>

 The value represents symmetric key as a byte array.

-=item "key-length" (B<SKEY_PARAM_KEY_LENGTH>) <integer>
+=item "key-length" (B<OSSL_SKEY_PARAM_KEY_LENGTH>) <integer>

 The value is the byte length of the given key.

+=item "skey-alias" (B<OSSL_SKEY_PARAM_ALIAS>) <UTF8 string>
+
+The friendly name (alias) for the key.  This is used as the return value
+from OSSL_FUNC_skeymgmt_get_key_id().  May be NULL.
+
+=item "skey-local-keyid" (B<OSSL_SKEY_PARAM_LOCAL_KEYID>) <octet string>
+
+The local key ID, typically originating from PKCS#12 bag attributes.
+Represented as a byte array with an associated length.  May be NULL.
+
+=item "skey-algorithm-oid" (B<OSSL_SKEY_PARAM_ALGORITHM_OID>) <octet string>
+
+The DER-encoded algorithm OID from the AlgorithmIdentifier.  May be NULL.
+
+=item "skey-algorithm-params" (B<OSSL_SKEY_PARAM_ALGORITHM_PARAMS>) <octet string>
+
+The DER-encoded algorithm parameters from the AlgorithmIdentifier.
+May be NULL.
+
 =back

 =head1 RETURN VALUES
@@ -176,6 +219,9 @@ OSSL_FUNC_skeymgmt_export() returns 1 for success or 0 on error.

 OSSL_FUNC_skeymgmt_get_key_id() returns a pointer to a 0-terminated string or NULL.

+OSSL_FUNC_skeymgmt_get_local_keyid() and OSSL_FUNC_skeymgmt_get_algorithm_id()
+return 1 on success or 0 on error.
+
 OSSL_FUNC_skeymgmt_gen_settable_params() and OSSL_FUNC_skeymgmt_imp_settable_params()
 return references to an array of B<OSSL_PARAM> which can be NULL if there are
 no settable parameters.
diff --git a/include/internal/skey.h b/include/internal/skey.h
index b511af8c32..68661aba8a 100644
--- a/include/internal/skey.h
+++ b/include/internal/skey.h
@@ -31,6 +31,15 @@ struct prov_skey_st {

     unsigned char *data;
     size_t length;
+
+    /* Metadata — set during import, returned during export / get_key_id */
+    char *alias;
+    unsigned char *local_keyid;
+    size_t local_keyid_len;
+    unsigned char *algorithm_oid;
+    size_t algorithm_oid_len;
+    unsigned char *algorithm_params;
+    size_t algorithm_params_len;
 };

 #endif /* OSSL_CRYPTO_SKEY_H */
diff --git a/include/openssl/core_dispatch.h b/include/openssl/core_dispatch.h
index 1bab83d792..176f8c426c 100644
--- a/include/openssl/core_dispatch.h
+++ b/include/openssl/core_dispatch.h
@@ -488,6 +488,8 @@ OSSL_CORE_MAKE_FUNC(int, mac_init_skey, (void *mctx, void *key, const OSSL_PARAM
 #define OSSL_FUNC_SKEYMGMT_GET_KEY_ID 5
 #define OSSL_FUNC_SKEYMGMT_IMP_SETTABLE_PARAMS 6
 #define OSSL_FUNC_SKEYMGMT_GEN_SETTABLE_PARAMS 7
+#define OSSL_FUNC_SKEYMGMT_GET_LOCAL_KEYID 8
+#define OSSL_FUNC_SKEYMGMT_GET_ALGORITHM_ID 9

 OSSL_CORE_MAKE_FUNC(void, skeymgmt_free, (void *keydata))
 OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *,
@@ -500,6 +502,12 @@ OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *,
     skeymgmt_gen_settable_params, (void *provctx))
 OSSL_CORE_MAKE_FUNC(void *, skeymgmt_generate, (void *provctx, const OSSL_PARAM params[]))
 OSSL_CORE_MAKE_FUNC(const char *, skeymgmt_get_key_id, (void *keydata))
+OSSL_CORE_MAKE_FUNC(int, skeymgmt_get_local_keyid,
+    (void *keydata, const unsigned char **id, size_t *len))
+OSSL_CORE_MAKE_FUNC(int, skeymgmt_get_algorithm_id,
+    (void *keydata,
+        const unsigned char **oid, size_t *oid_len,
+        const unsigned char **params, size_t *params_len))

 /* KDFs and PRFs */

diff --git a/include/openssl/evp.h b/include/openssl/evp.h
index dcbc5b26d3..55503411eb 100644
--- a/include/openssl/evp.h
+++ b/include/openssl/evp.h
@@ -1950,6 +1950,11 @@ const char *EVP_SKEY_get0_skeymgmt_name(const EVP_SKEY *skey);
 const char *EVP_SKEY_get0_provider_name(const EVP_SKEY *skey);
 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);

 /*
  * The seemingly redundant expression (char *)(strstr(curve, "")) serves to
diff --git a/providers/implementations/include/prov/skeymgmt_lcl.h b/providers/implementations/include/prov/skeymgmt_lcl.h
index 7e35b2cc9e..db42967c7a 100644
--- a/providers/implementations/include/prov/skeymgmt_lcl.h
+++ b/providers/implementations/include/prov/skeymgmt_lcl.h
@@ -16,5 +16,8 @@ OSSL_FUNC_skeymgmt_import_fn generic_import;
 OSSL_FUNC_skeymgmt_export_fn generic_export;
 OSSL_FUNC_skeymgmt_free_fn generic_free;
 OSSL_FUNC_skeymgmt_imp_settable_params_fn generic_imp_settable_params;
+OSSL_FUNC_skeymgmt_get_key_id_fn generic_get_key_id;
+OSSL_FUNC_skeymgmt_get_local_keyid_fn generic_get_local_keyid;
+OSSL_FUNC_skeymgmt_get_algorithm_id_fn generic_get_algorithm_id;

 #endif
diff --git a/providers/implementations/skeymgmt/aes_skmgmt.c b/providers/implementations/skeymgmt/aes_skmgmt.c
index 87bd76d08b..e49c09dbd3 100644
--- a/providers/implementations/skeymgmt/aes_skmgmt.c
+++ b/providers/implementations/skeymgmt/aes_skmgmt.c
@@ -50,5 +50,10 @@ const OSSL_DISPATCH ossl_aes_skeymgmt_functions[] = {
     { OSSL_FUNC_SKEYMGMT_EXPORT, (void (*)(void))aes_export },
     { OSSL_FUNC_SKEYMGMT_IMP_SETTABLE_PARAMS,
         (void (*)(void))generic_imp_settable_params },
+    { OSSL_FUNC_SKEYMGMT_GET_KEY_ID, (void (*)(void))generic_get_key_id },
+    { OSSL_FUNC_SKEYMGMT_GET_LOCAL_KEYID,
+        (void (*)(void))generic_get_local_keyid },
+    { OSSL_FUNC_SKEYMGMT_GET_ALGORITHM_ID,
+        (void (*)(void))generic_get_algorithm_id },
     OSSL_DISPATCH_END
 };
diff --git a/providers/implementations/skeymgmt/generic.c b/providers/implementations/skeymgmt/generic.c
index 9508c3a5fb..769e6fa939 100644
--- a/providers/implementations/skeymgmt/generic.c
+++ b/providers/implementations/skeymgmt/generic.c
@@ -29,10 +29,62 @@ void generic_free(void *keydata)
         return;

     OPENSSL_clear_free(generic->data, generic->length);
+    OPENSSL_free(generic->alias);
+    OPENSSL_free(generic->local_keyid);
+    OPENSSL_free(generic->algorithm_oid);
+    OPENSSL_free(generic->algorithm_params);
     OPENSSL_free(generic);
 }

-void *generic_import(void *provctx, int selection, const OSSL_PARAM params[])
+static int generic_import_metadata(PROV_SKEY *skey,
+    const struct generic_skey_import_st *p)
+{
+    if (p->alias != NULL
+        && p->alias->data_type == OSSL_PARAM_UTF8_STRING
+        && skey->alias == NULL) {
+        skey->alias = OPENSSL_strndup(p->alias->data, p->alias->data_size);
+        if (skey->alias == NULL)
+            return 0;
+        if (strlen(skey->alias) != p->alias->data_size) {
+            ERR_raise(ERR_R_PROV_LIB, PROV_R_INVALID_DATA);
+            return 0;
+        }
+    }
+
+    if (p->local_keyid != NULL
+        && p->local_keyid->data_type == OSSL_PARAM_OCTET_STRING
+        && skey->local_keyid == NULL) {
+        skey->local_keyid = OPENSSL_memdup(p->local_keyid->data,
+            p->local_keyid->data_size);
+        if (skey->local_keyid == NULL)
+            return 0;
+        skey->local_keyid_len = p->local_keyid->data_size;
+    }
+
+    if (p->algorithm_oid != NULL
+        && p->algorithm_oid->data_type == OSSL_PARAM_OCTET_STRING
+        && skey->algorithm_oid == NULL) {
+        skey->algorithm_oid = OPENSSL_memdup(p->algorithm_oid->data,
+            p->algorithm_oid->data_size);
+        if (skey->algorithm_oid == NULL)
+            return 0;
+        skey->algorithm_oid_len = p->algorithm_oid->data_size;
+    }
+
+    if (p->algorithm_params != NULL
+        && p->algorithm_params->data_type == OSSL_PARAM_OCTET_STRING
+        && skey->algorithm_params == NULL) {
+        skey->algorithm_params = OPENSSL_memdup(p->algorithm_params->data,
+            p->algorithm_params->data_size);
+        if (skey->algorithm_params == NULL)
+            return 0;
+        skey->algorithm_params_len = p->algorithm_params->data_size;
+    }
+
+    return 1;
+}
+
+void *generic_import(void *provctx, int selection ossl_unused, const OSSL_PARAM params[])
 {
     OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(provctx);
     struct generic_skey_import_st p;
@@ -42,9 +94,6 @@ void *generic_import(void *provctx, int selection, const OSSL_PARAM params[])
     if (!ossl_prov_is_running())
         return NULL;

-    if ((selection & OSSL_SKEYMGMT_SELECT_SECRET_KEY) == 0)
-        return NULL;
-
     if (!generic_skey_import_decoder(params, &p))
         return NULL;

@@ -65,6 +114,10 @@ void *generic_import(void *provctx, int selection, const OSSL_PARAM params[])
         == NULL)
         goto end;
     generic->length = p.raw_bytes->data_size;
+
+    if (!generic_import_metadata(generic, &p))
+        goto end;
+
     ok = 1;

 end:
@@ -84,27 +137,107 @@ int generic_export(void *keydata, int selection,
     OSSL_CALLBACK *param_callback, void *cbarg)
 {
     PROV_SKEY *gen = keydata;
-    OSSL_PARAM params[2];
+    OSSL_PARAM params[6];
+    int idx = 0;

-    if (!ossl_prov_is_running() || gen == NULL)
+    if (!ossl_prov_is_running() || gen == NULL || selection == 0)
         return 0;

     /* If we use generic SKEYMGMT as a "base class", we shouldn't check the type */
-    if ((selection & OSSL_SKEYMGMT_SELECT_SECRET_KEY) == 0)
-        return 0;
+    if ((selection & OSSL_SKEYMGMT_SELECT_SECRET_KEY) != 0)
+        params[idx++] = OSSL_PARAM_construct_octet_string(OSSL_SKEY_PARAM_RAW_BYTES,
+            gen->data, gen->length);
+
+    if ((selection & OSSL_SKEYMGMT_SELECT_PARAMETERS) != 0) {
+        if (gen->alias != NULL)
+            params[idx++] = OSSL_PARAM_construct_utf8_string(
+                OSSL_SKEY_PARAM_ALIAS, gen->alias, 0);
+
+        if (gen->local_keyid != NULL)
+            params[idx++] = OSSL_PARAM_construct_octet_string(
+                OSSL_SKEY_PARAM_LOCAL_KEYID,
+                gen->local_keyid, gen->local_keyid_len);
+
+        if (gen->algorithm_oid != NULL)
+            params[idx++] = OSSL_PARAM_construct_octet_string(
+                OSSL_SKEY_PARAM_ALGORITHM_OID,
+                gen->algorithm_oid, gen->algorithm_oid_len);
+
+        if (gen->algorithm_params != NULL)
+            params[idx++] = OSSL_PARAM_construct_octet_string(
+                OSSL_SKEY_PARAM_ALGORITHM_PARAMS,
+                gen->algorithm_params, gen->algorithm_params_len);
+    }

-    params[0] = OSSL_PARAM_construct_octet_string(OSSL_SKEY_PARAM_RAW_BYTES,
-        gen->data, gen->length);
-    params[1] = OSSL_PARAM_construct_end();
+    params[idx] = OSSL_PARAM_construct_end();

     return param_callback(params, cbarg);
 }

+const char *generic_get_key_id(void *keydata)
+{
+    PROV_SKEY *gen = keydata;
+
+    if (gen == NULL)
+        return NULL;
+
+    return gen->alias;
+}
+
+int generic_get_local_keyid(void *keydata,
+    const unsigned char **id, size_t *len)
+{
+    PROV_SKEY *gen = keydata;
+
+    if (gen == NULL)
+        return 0;
+    if (id == NULL || len == NULL)
+        return 0;
+
+    *id = gen->local_keyid;
+    *len = gen->local_keyid_len;
+    return 1;
+}
+
+int generic_get_algorithm_id(void *keydata,
+    const unsigned char **oid, size_t *oid_len,
+    const unsigned char **params, size_t *params_len)
+{
+    PROV_SKEY *gen = keydata;
+    int ret_oid = 0, ret_params = 0;
+
+    if (gen == NULL)
+        return 0;
+
+    if (oid != NULL && oid_len != NULL)
+        ret_oid = 1;
+    if (params != NULL && params_len != NULL)
+        ret_params = 1;
+
+    if (ret_oid == 0 && ret_params == 0)
+        return 0;
+
+    if (ret_oid == 1) {
+        *oid = gen->algorithm_oid;
+        *oid_len = gen->algorithm_oid_len;
+    }
+    if (ret_params == 1) {
+        *params = gen->algorithm_params;
+        *params_len = gen->algorithm_params_len;
+    }
+    return 1;
+}
+
 const OSSL_DISPATCH ossl_generic_skeymgmt_functions[] = {
     { OSSL_FUNC_SKEYMGMT_FREE, (void (*)(void))generic_free },
     { OSSL_FUNC_SKEYMGMT_IMPORT, (void (*)(void))generic_import },
     { OSSL_FUNC_SKEYMGMT_EXPORT, (void (*)(void))generic_export },
     { OSSL_FUNC_SKEYMGMT_IMP_SETTABLE_PARAMS,
         (void (*)(void))generic_imp_settable_params },
+    { OSSL_FUNC_SKEYMGMT_GET_KEY_ID, (void (*)(void))generic_get_key_id },
+    { OSSL_FUNC_SKEYMGMT_GET_LOCAL_KEYID,
+        (void (*)(void))generic_get_local_keyid },
+    { OSSL_FUNC_SKEYMGMT_GET_ALGORITHM_ID,
+        (void (*)(void))generic_get_algorithm_id },
     OSSL_DISPATCH_END
 };
diff --git a/providers/implementations/skeymgmt/generic.inc.in b/providers/implementations/skeymgmt/generic.inc.in
index 6f30d5bce1..4c77928423 100644
--- a/providers/implementations/skeymgmt/generic.inc.in
+++ b/providers/implementations/skeymgmt/generic.inc.in
@@ -11,5 +11,9 @@ use OpenSSL::paramnames qw(produce_param_decoder);
 -}

 {- produce_param_decoder('generic_skey_import',
-                         (['OSSL_SKEY_PARAM_RAW_BYTES',  'raw_bytes',    'octet_string'],
+                         (['OSSL_SKEY_PARAM_RAW_BYTES',       'raw_bytes',        'octet_string'],
+                          ['OSSL_SKEY_PARAM_ALIAS',           'alias',            'utf8_string'],
+                          ['OSSL_SKEY_PARAM_LOCAL_KEYID',     'local_keyid',      'octet_string'],
+                          ['OSSL_SKEY_PARAM_ALGORITHM_OID',   'algorithm_oid',    'octet_string'],
+                          ['OSSL_SKEY_PARAM_ALGORITHM_PARAMS','algorithm_params', 'octet_string'],
                          )); -}
diff --git a/test/evp_skey_test.c b/test/evp_skey_test.c
index 631a5a6287..3ff4d93676 100644
--- a/test/evp_skey_test.c
+++ b/test/evp_skey_test.c
@@ -113,7 +113,7 @@ static int test_skey_skeymgmt(void)
     if (!TEST_ptr(deflprov))
         return 0;

-    /* Fetch our SKYMGMT for Generic Secrets */
+    /* Fetch our SKEYMGMT for Generic Secrets */
     if (!TEST_ptr(skeymgmt = EVP_SKEYMGMT_fetch(libctx, OSSL_SKEY_TYPE_GENERIC,
                       NULL)))
         goto end;
@@ -308,6 +308,235 @@ end:
 }
 #endif

+static int test_skey_metadata_import(int tst)
+{
+    int ret = 0;
+    EVP_SKEY *key = NULL;
+    OSSL_PARAM_BLD *bld = NULL;
+    OSSL_PARAM *params = NULL;
+    OSSL_PARAM *exp_params = NULL;
+    const unsigned char import_key[KEY_SIZE] = {
+        0x53, 0x4B, 0x45, 0x59, 0x53, 0x4B, 0x45, 0x59, 0x53, 0x4B,
+        0x45, 0x59, 0x53, 0x4B, 0x45, 0x59
+    };
+    const char *alias = "my friendly name";
+    const unsigned char local_keyid[] = { 0x01, 0x02, 0x03, 0x04 };
+    const unsigned char alg_oid[] = { 0x06, 0x09, 0x60, 0x86, 0x48,
+        0x01, 0x65, 0x03, 0x04, 0x01, 0x02 };
+    const unsigned char alg_params[] = { 0x04, 0x10, 0x00, 0x01, 0x02, 0x03 };
+    const char *bad_alias = "bad\0alias";
+    const unsigned char *out_id = NULL;
+    size_t out_len = 0;
+    const unsigned char *out_oid = NULL, *out_params = NULL;
+    size_t out_oid_len = 0, out_params_len = 0;
+
+    deflprov = OSSL_PROVIDER_load(libctx, "default");
+    if (!TEST_ptr(deflprov))
+        return 0;
+
+    if (!TEST_ptr(bld = OSSL_PARAM_BLD_new()))
+        goto end;
+
+    if (!TEST_int_gt(OSSL_PARAM_BLD_push_octet_string(bld,
+                         OSSL_SKEY_PARAM_RAW_BYTES,
+                         import_key, sizeof(import_key)),
+            0))
+        goto end;
+
+    switch (tst) {
+    case 0:
+        /* Import with all metadata */
+        if (!TEST_int_gt(OSSL_PARAM_BLD_push_utf8_string(bld,
+                             OSSL_SKEY_PARAM_ALIAS, alias, 0),
+                0)
+            || !TEST_int_gt(OSSL_PARAM_BLD_push_octet_string(bld,
+                                OSSL_SKEY_PARAM_LOCAL_KEYID,
+                                local_keyid, sizeof(local_keyid)),
+                0)
+            || !TEST_int_gt(OSSL_PARAM_BLD_push_octet_string(bld,
+                                OSSL_SKEY_PARAM_ALGORITHM_OID,
+                                alg_oid, sizeof(alg_oid)),
+                0)
+            || !TEST_int_gt(OSSL_PARAM_BLD_push_octet_string(bld,
+                                OSSL_SKEY_PARAM_ALGORITHM_PARAMS,
+                                alg_params, sizeof(alg_params)),
+                0))
+            goto end;
+        break;
+    case 1:
+        /* Import with no metadata — should succeed */
+        break;
+    case 2:
+        /* Import with alias containing embedded NUL — should fail */
+        if (!TEST_int_gt(OSSL_PARAM_BLD_push_utf8_string(bld,
+                             OSSL_SKEY_PARAM_ALIAS,
+                             bad_alias, sizeof("bad\0alias") - 1),
+                0))
+            goto end;
+        break;
+    default:
+        goto end;
+    }
+
+    if (!TEST_ptr(params = OSSL_PARAM_BLD_to_param(bld)))
+        goto end;
+
+    key = EVP_SKEY_import(libctx, OSSL_SKEY_TYPE_GENERIC, NULL,
+        OSSL_SKEYMGMT_SELECT_ALL, params);
+
+    if (tst == 2) {
+        /* Embedded NUL in alias must cause import failure */
+        if (!TEST_ptr_null(key))
+            goto end;
+        ret = 1;
+        goto end;
+    }
+
+    if (!TEST_ptr(key))
+        goto end;
+
+    if (tst == 0) {
+        /* Verify alias via get0_key_id */
+        if (!TEST_str_eq(EVP_SKEY_get0_key_id(key), alias))
+            goto end;
+
+        /* Verify local_keyid */
+        if (!TEST_int_gt(EVP_SKEY_get0_local_keyid(key, &out_id, &out_len), 0)
+            || !TEST_mem_eq(out_id, out_len, local_keyid, sizeof(local_keyid)))
+            goto end;
+
+        /* Verify algorithm_id */
+        if (!TEST_int_gt(EVP_SKEY_get0_algorithm_id(key,
+                             &out_oid, &out_oid_len,
+                             &out_params, &out_params_len),
+                0)
+            || !TEST_mem_eq(out_oid, out_oid_len, alg_oid, sizeof(alg_oid))
+            || !TEST_mem_eq(out_params, out_params_len,
+                alg_params, sizeof(alg_params)))
+            goto end;
+    }
+
+    if (tst == 1) {
+        /* No metadata — get0_key_id should return NULL */
+        if (!TEST_ptr_null(EVP_SKEY_get0_key_id(key)))
+            goto end;
+        /* get0_local_keyid succeeds but returns NULL pointer */
+        if (!TEST_int_gt(EVP_SKEY_get0_local_keyid(key, &out_id, &out_len), 0)
+            || !TEST_ptr_null(out_id)
+            || !TEST_size_t_eq(out_len, 0))
+            goto end;
+    }
+
+    ret = 1;
+end:
+    OSSL_PARAM_free(params);
+    OSSL_PARAM_free(exp_params);
+    OSSL_PARAM_BLD_free(bld);
+    EVP_SKEY_free(key);
+    OSSL_PROVIDER_unload(deflprov);
+    return ret;
+}
+
+static int test_skey_metadata_export(int tst)
+{
+    int ret = 0;
+    EVP_SKEY *key = NULL;
+    OSSL_PARAM_BLD *bld = NULL;
+    OSSL_PARAM *params = NULL;
+    OSSL_PARAM *exp_params = NULL;
+    const OSSL_PARAM *p;
+    const unsigned char import_key[KEY_SIZE] = {
+        0x53, 0x4B, 0x45, 0x59, 0x53, 0x4B, 0x45, 0x59, 0x53, 0x4B,
+        0x45, 0x59, 0x53, 0x4B, 0x45, 0x59
+    };
+    const char *alias = "export test alias";
+    const unsigned char local_keyid[] = { 0xAA, 0xBB, 0xCC };
+    int export_ret;
+
+    deflprov = OSSL_PROVIDER_load(libctx, "default");
+    if (!TEST_ptr(deflprov))
+        return 0;
+
+    if (!TEST_ptr(bld = OSSL_PARAM_BLD_new()))
+        goto end;
+
+    if (!TEST_int_gt(OSSL_PARAM_BLD_push_octet_string(bld,
+                         OSSL_SKEY_PARAM_RAW_BYTES,
+                         import_key, sizeof(import_key)),
+            0)
+        || !TEST_int_gt(OSSL_PARAM_BLD_push_utf8_string(bld,
+                            OSSL_SKEY_PARAM_ALIAS, alias, 0),
+            0)
+        || !TEST_int_gt(OSSL_PARAM_BLD_push_octet_string(bld,
+                            OSSL_SKEY_PARAM_LOCAL_KEYID,
+                            local_keyid, sizeof(local_keyid)),
+            0))
+        goto end;
+
+    if (!TEST_ptr(params = OSSL_PARAM_BLD_to_param(bld)))
+        goto end;
+
+    key = EVP_SKEY_import(libctx, OSSL_SKEY_TYPE_GENERIC, NULL,
+        OSSL_SKEYMGMT_SELECT_ALL, params);
+    if (!TEST_ptr(key))
+        goto end;
+
+    switch (tst) {
+    case 0:
+        /* Export SECRET_KEY only — should not include metadata params */
+        if (!TEST_int_gt(EVP_SKEY_export(key,
+                             OSSL_SKEYMGMT_SELECT_SECRET_KEY,
+                             ossl_pkey_todata_cb, &exp_params),
+                0))
+            goto end;
+        if (!TEST_ptr(OSSL_PARAM_locate_const(exp_params,
+                OSSL_SKEY_PARAM_RAW_BYTES)))
+            goto end;
+        if (!TEST_ptr_null(OSSL_PARAM_locate_const(exp_params,
+                OSSL_SKEY_PARAM_ALIAS)))
+            goto end;
+        if (!TEST_ptr_null(OSSL_PARAM_locate_const(exp_params,
+                OSSL_SKEY_PARAM_LOCAL_KEYID)))
+            goto end;
+        break;
+    case 1:
+        /* Export PARAMETERS only — should not include raw bytes */
+        if (!TEST_int_gt(EVP_SKEY_export(key,
+                             OSSL_SKEYMGMT_SELECT_PARAMETERS,
+                             ossl_pkey_todata_cb, &exp_params),
+                0))
+            goto end;
+        if (!TEST_ptr_null(OSSL_PARAM_locate_const(exp_params,
+                OSSL_SKEY_PARAM_RAW_BYTES)))
+            goto end;
+        if (!TEST_ptr(p = OSSL_PARAM_locate_const(exp_params,
+                          OSSL_SKEY_PARAM_ALIAS)))
+            goto end;
+        if (!TEST_ptr(OSSL_PARAM_locate_const(exp_params,
+                OSSL_SKEY_PARAM_LOCAL_KEYID)))
+            goto end;
+        break;
+    case 2:
+        /* Export with selection 0 — should fail */
+        export_ret = EVP_SKEY_export(key, 0,
+            ossl_pkey_todata_cb, &exp_params);
+        if (!TEST_int_le(export_ret, 0))
+            goto end;
+        break;
+    default:
+        goto end;
+    }
+
+    ret = 1;
+end:
+    OSSL_PARAM_free(params);
+    OSSL_PARAM_free(exp_params);
+    OSSL_PARAM_BLD_free(bld);
+    EVP_SKEY_free(key);
+    OSSL_PROVIDER_unload(deflprov);
+    return ret;
+}
+
 static int test_skey_to_same_provider(void)
 {
     OSSL_PROVIDER *fake_prov = NULL;
@@ -402,6 +631,8 @@ int setup_tests(void)
     ADD_TEST(test_skey_cipher);
     ADD_TEST(test_skey_skeymgmt);

+    ADD_ALL_TESTS(test_skey_metadata_import, 3);
+    ADD_ALL_TESTS(test_skey_metadata_export, 3);
     ADD_TEST(test_skey_to_same_provider);
     ADD_TEST(test_skey_to_diff_provider);
     ADD_TEST(test_aes_raw_skey);
diff --git a/util/libcrypto.num b/util/libcrypto.num
index c4a9d2b4c5..a2ff5af75e 100644
--- a/util/libcrypto.num
+++ b/util/libcrypto.num
@@ -5717,6 +5717,8 @@ OSSL_ESS_check_signing_certs_ex         5714	4_0_0	EXIST::FUNCTION:
 X509v3_delete_extension                 5715	4_0_0	EXIST::FUNCTION:
 CMS_SignerInfo_get0_signer_cert         ?	4_1_0	EXIST::FUNCTION:CMS
 CMS_SignerInfo_get_verification_result  ?	4_1_0	EXIST::FUNCTION:CMS
+EVP_SKEY_get0_local_keyid               ?	4_1_0	EXIST::FUNCTION:
+EVP_SKEY_get0_algorithm_id              ?	4_1_0	EXIST::FUNCTION:
 CTLOG_STORE_add0_log                    ?	4_1_0	EXIST::FUNCTION:CT
 CRYPTO_atomic_load_ptr                  ?	4_1_0	EXIST::FUNCTION:
 CRYPTO_atomic_store_ptr                 ?	4_1_0	EXIST::FUNCTION:
diff --git a/util/perl/OpenSSL/paramnames.pm b/util/perl/OpenSSL/paramnames.pm
index 23dd031665..dd34cee7d8 100644
--- a/util/perl/OpenSSL/paramnames.pm
+++ b/util/perl/OpenSSL/paramnames.pm
@@ -647,8 +647,12 @@ my %params = (
     'OSSL_LIBSSL_RECORD_LAYER_PARAM_HS_PADDING' =>     "hs_padding",

 # Symmetric Key parameters
-    'OSSL_SKEY_PARAM_RAW_BYTES' => "raw-bytes",
+    'OSSL_SKEY_PARAM_ALIAS' => "skey-alias",
+    'OSSL_SKEY_PARAM_ALGORITHM_OID' => "skey-algorithm-oid",
+    'OSSL_SKEY_PARAM_ALGORITHM_PARAMS' => "skey-algorithm-params",
     'OSSL_SKEY_PARAM_KEY_LENGTH' => "key-length",
+    'OSSL_SKEY_PARAM_LOCAL_KEYID' => "skey-local-keyid",
+    'OSSL_SKEY_PARAM_RAW_BYTES' => "raw-bytes",
 );

 sub output_ifdef {