EVP: make EVP_PKEY_{bits,security_bits,size} work with provider only keys
authorRichard Levitte <levitte@openssl.org>
Wed, 8 Jan 2020 02:44:28 +0000 (03:44 +0100)
committerRichard Levitte <levitte@openssl.org>
Fri, 17 Jan 2020 08:04:04 +0000 (09:04 +0100)
These functions relied entirely on the presence of 'pkey->pmeth',
which is NULL on provider only keys.  This adds an interface to get
domparam and key data from a provider, given corresponding provider
data (the actual domparam or key).

The retrieved data is cached in the EVP_PKEY structure (lending the
idea from provided EVP_CIPHER).

Reviewed-by: Nicola Tuveri <nic.tuv@gmail.com>
(Merged from https://github.com/openssl/openssl/pull/10778)

crypto/evp/evp_local.h
crypto/evp/keymgmt_lib.c
crypto/evp/keymgmt_meth.c
crypto/evp/p_lib.c
doc/man7/provider-keymgmt.pod
include/crypto/evp.h
include/openssl/core_names.h
include/openssl/core_numbers.h

index de73267c98fe1904d9ae829e1e6962e73ef5d95c..0feace2aa5b60f23392eb1f3c24f9a1d49494248 100644 (file)
@@ -80,6 +80,8 @@ struct evp_keymgmt_st {
     OSSL_OP_keymgmt_exportdomparams_fn *exportdomparams;
     OSSL_OP_keymgmt_importdomparam_types_fn *importdomparam_types;
     OSSL_OP_keymgmt_exportdomparam_types_fn *exportdomparam_types;
+    OSSL_OP_keymgmt_get_domparam_params_fn *get_domparam_params;
+    OSSL_OP_keymgmt_gettable_domparam_params_fn *gettable_domparam_params;
 
     /* Key routines */
     OSSL_OP_keymgmt_importkey_fn *importkey;
@@ -89,6 +91,9 @@ struct evp_keymgmt_st {
     OSSL_OP_keymgmt_exportkey_fn *exportkey;
     OSSL_OP_keymgmt_importkey_types_fn *importkey_types;
     OSSL_OP_keymgmt_exportkey_types_fn *exportkey_types;
+    OSSL_OP_keymgmt_get_key_params_fn *get_key_params;
+    OSSL_OP_keymgmt_gettable_key_params_fn *gettable_key_params;
+
     OSSL_OP_keymgmt_query_operation_name_fn *query_operation_name;
 } /* EVP_KEYMGMT */ ;
 
index 4163bca5bbb3ead5b5a73369eb72c055e4fc19c9..53610d3ef87acb8a25d4dcdd60e0d15cf5a2e132 100644 (file)
@@ -7,6 +7,7 @@
  * https://www.openssl.org/source/license.html
  */
 
+#include <openssl/core_names.h>
 #include "internal/cryptlib.h"
 #include "internal/nelem.h"
 #include "crypto/evp.h"
@@ -132,12 +133,7 @@ void *evp_keymgmt_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt,
      */
     j = ossl_assert(i < OSSL_NELEM(pk->pkeys));
 
-    if (provdata != NULL) {
-        EVP_KEYMGMT_up_ref(keymgmt);
-        pk->pkeys[i].keymgmt = keymgmt;
-        pk->pkeys[i].provdata = provdata;
-        pk->pkeys[i].domainparams = want_domainparams;
-    }
+    evp_keymgmt_cache_pkey(pk, i, keymgmt, provdata, want_domainparams);
 
     return provdata;
 }
@@ -161,6 +157,49 @@ void evp_keymgmt_clear_pkey_cache(EVP_PKEY *pk)
                 keymgmt->freekey(provdata);
             EVP_KEYMGMT_free(keymgmt);
         }
+
+        pk->cache.size = 0;
+        pk->cache.bits = 0;
+        pk->cache.security_bits = 0;
+    }
+}
+
+void evp_keymgmt_cache_pkey(EVP_PKEY *pk, size_t index, EVP_KEYMGMT *keymgmt,
+                            void *provdata, int domainparams)
+{
+    if (provdata != NULL) {
+        EVP_KEYMGMT_up_ref(keymgmt);
+        pk->pkeys[index].keymgmt = keymgmt;
+        pk->pkeys[index].provdata = provdata;
+        pk->pkeys[index].domainparams = domainparams;
+
+        /*
+         * Cache information about the domain parameters or key.  Only needed
+         * for the "original" provider side key.
+         *
+         * This services functions like EVP_PKEY_size, EVP_PKEY_bits, etc
+         */
+        if (index == 0) {
+            int ok;
+            int bits = 0;
+            int security_bits = 0;
+            int size = 0;
+            OSSL_PARAM params[4];
+
+            params[0] = OSSL_PARAM_construct_int(OSSL_PKEY_PARAM_BITS, &bits);
+            params[1] = OSSL_PARAM_construct_int(OSSL_PKEY_PARAM_SECURITY_BITS,
+                                                 &security_bits);
+            params[2] = OSSL_PARAM_construct_int(OSSL_PKEY_PARAM_MAX_SIZE, &size);
+            params[3] = OSSL_PARAM_construct_end();
+            ok = domainparams
+                ? evp_keymgmt_get_domparam_params(keymgmt, provdata, params)
+                : evp_keymgmt_get_key_params(keymgmt, provdata, params);
+            if (ok) {
+                pk->cache.size = size;
+                pk->cache.bits = bits;
+                pk->cache.security_bits = security_bits;
+            }
+        }
     }
 }
 
@@ -173,12 +212,7 @@ void *evp_keymgmt_fromdata(EVP_PKEY *target, EVP_KEYMGMT *keymgmt,
         : keymgmt->importkey(provctx, params);
 
     evp_keymgmt_clear_pkey_cache(target);
-    if (provdata != NULL) {
-        EVP_KEYMGMT_up_ref(keymgmt);
-        target->pkeys[0].keymgmt = keymgmt;
-        target->pkeys[0].provdata = provdata;
-        target->pkeys[0].domainparams = domainparams;
-    }
+    evp_keymgmt_cache_pkey(target, 0, keymgmt, provdata, domainparams);
 
     return provdata;
 }
@@ -228,6 +262,22 @@ const OSSL_PARAM *evp_keymgmt_exportdomparam_types(const EVP_KEYMGMT *keymgmt)
     return keymgmt->exportdomparam_types();
 }
 
+int evp_keymgmt_get_domparam_params(const EVP_KEYMGMT *keymgmt,
+                                     void *provdomparams, OSSL_PARAM params[])
+{
+    if (keymgmt->get_domparam_params == NULL)
+        return 1;
+    return keymgmt->get_domparam_params(provdomparams, params);
+}
+
+const OSSL_PARAM *
+evp_keymgmt_gettable_domparam_params(const EVP_KEYMGMT *keymgmt)
+{
+    if (keymgmt->gettable_domparam_params == NULL)
+        return NULL;
+    return keymgmt->gettable_domparam_params();
+}
+
 
 void *evp_keymgmt_importkey(const EVP_KEYMGMT *keymgmt,
                             const OSSL_PARAM params[])
@@ -277,3 +327,18 @@ const OSSL_PARAM *evp_keymgmt_exportkey_types(const EVP_KEYMGMT *keymgmt)
 {
     return keymgmt->exportkey_types();
 }
+
+int evp_keymgmt_get_key_params(const EVP_KEYMGMT *keymgmt,
+                               void *provkey, OSSL_PARAM params[])
+{
+    if (keymgmt->get_key_params == NULL)
+        return 1;
+    return keymgmt->get_key_params(provkey, params);
+}
+
+const OSSL_PARAM *evp_keymgmt_gettable_key_params(const EVP_KEYMGMT *keymgmt)
+{
+    if (keymgmt->gettable_key_params == NULL)
+        return NULL;
+    return keymgmt->gettable_key_params();
+}
index 03d1686cf3230cee4f9816317355f439e66ed3f2..ae1f10e6b3606faba1e5ba2ce666a9065515561a 100644 (file)
@@ -81,6 +81,16 @@ static void *keymgmt_from_dispatch(int name_id,
             keymgmt->exportdomparam_types =
                 OSSL_get_OP_keymgmt_exportdomparam_types(fns);
             break;
+        case OSSL_FUNC_KEYMGMT_GET_DOMPARAM_PARAMS:
+            if (keymgmt->get_domparam_params == NULL)
+                keymgmt->get_domparam_params =
+                    OSSL_get_OP_keymgmt_get_domparam_params(fns);
+            break;
+        case OSSL_FUNC_KEYMGMT_GETTABLE_DOMPARAM_PARAMS:
+            if (keymgmt->gettable_domparam_params == NULL)
+                keymgmt->gettable_domparam_params =
+                    OSSL_get_OP_keymgmt_gettable_domparam_params(fns);
+            break;
         case OSSL_FUNC_KEYMGMT_IMPORTKEY:
             if (keymgmt->importkey != NULL)
                 break;
@@ -118,6 +128,16 @@ static void *keymgmt_from_dispatch(int name_id,
             keymgmt->exportkey_types =
                 OSSL_get_OP_keymgmt_exportkey_types(fns);
             break;
+        case OSSL_FUNC_KEYMGMT_GET_KEY_PARAMS:
+            if (keymgmt->get_key_params == NULL)
+                keymgmt->get_key_params =
+                    OSSL_get_OP_keymgmt_get_key_params(fns);
+            break;
+        case OSSL_FUNC_KEYMGMT_GETTABLE_KEY_PARAMS:
+            if (keymgmt->gettable_key_params == NULL)
+                keymgmt->gettable_key_params =
+                    OSSL_get_OP_keymgmt_gettable_key_params(fns);
+            break;
         case OSSL_FUNC_KEYMGMT_QUERY_OPERATION_NAME:
             if (keymgmt->query_operation_name != NULL)
                 break;
@@ -143,10 +163,14 @@ static void *keymgmt_from_dispatch(int name_id,
             && keymgmt->importdomparams == NULL)
         || (keymgmt->exportdomparam_types != NULL
             && keymgmt->exportdomparams == NULL)
+        || (keymgmt->gettable_domparam_params != NULL
+            && keymgmt->get_domparam_params == NULL)
         || (keymgmt->importkey_types != NULL
             && keymgmt->importkey == NULL)
         || (keymgmt->exportkey_types != NULL
-            && keymgmt->exportkey == NULL)) {
+            && keymgmt->exportkey == NULL)
+        || (keymgmt->gettable_key_params != NULL
+            && keymgmt->get_key_params == NULL)) {
         EVP_KEYMGMT_free(keymgmt);
         EVPerr(0, EVP_R_INVALID_PROVIDER_FUNCTIONS);
         return NULL;
index 5c11ce1b6ae2bb18b62fc33418eface526221830..2e0890cac51abe31e9369d7301aaf8cde80d7971 100644 (file)
@@ -34,8 +34,12 @@ static void evp_pkey_free_it(EVP_PKEY *key);
 
 int EVP_PKEY_bits(const EVP_PKEY *pkey)
 {
-    if (pkey && pkey->ameth && pkey->ameth->pkey_bits)
-        return pkey->ameth->pkey_bits(pkey);
+    if (pkey != NULL) {
+        if (pkey->ameth == NULL)
+            return pkey->cache.bits;
+        else if (pkey->ameth->pkey_bits)
+            return pkey->ameth->pkey_bits(pkey);
+    }
     return 0;
 }
 
@@ -43,7 +47,9 @@ int EVP_PKEY_security_bits(const EVP_PKEY *pkey)
 {
     if (pkey == NULL)
         return 0;
-    if (pkey->ameth == NULL || pkey->ameth->pkey_security_bits == NULL)
+    if (pkey->ameth == NULL)
+        return pkey->cache.security_bits;
+    if (pkey->ameth->pkey_security_bits == NULL)
         return -2;
     return pkey->ameth->pkey_security_bits(pkey);
 }
@@ -811,11 +817,13 @@ void EVP_PKEY_free(EVP_PKEY *x)
     OPENSSL_free(x);
 }
 
-/* TODO (3.0) : Needs to call getparams fo non legacy case */
 int EVP_PKEY_size(const EVP_PKEY *pkey)
 {
-    if (pkey && pkey->ameth && pkey->ameth->pkey_size)
-        return pkey->ameth->pkey_size(pkey);
+    if (pkey != NULL) {
+        if (pkey->ameth == NULL)
+            return pkey->cache.size;
+        else if (pkey->ameth->pkey_size != NULL)
+            return pkey->ameth->pkey_size(pkey);
+    }
     return 0;
 }
-
index 1c868c563085a7689b77793892e3ac606f03ecc5..adc1978a368876cca93f5befce58b3996e10911e 100644 (file)
@@ -26,6 +26,10 @@ provider-keymgmt - The KEYMGMT library E<lt>-E<gt> provider functions
  const OSSL_PARAM *OP_keymgmt_importdomparam_types(void);
  const OSSL_PARAM *OP_keymgmt_exportdomparam_types(void);
 
+ /* Key domain parameter information */
+ int OP_keymgmt_get_domparam_params(void *domparams, OSSL_PARAM params[]);
+ const OSSL_PARAM *OP_keymgmt_gettable_domparam_params(void);
+
  /* Key creation and destruction */
  void *OP_keymgmt_importkey(void *provctx, const OSSL_PARAM params[]);
  void *OP_keymgmt_genkey(void *provctx,
@@ -40,6 +44,10 @@ provider-keymgmt - The KEYMGMT library E<lt>-E<gt> provider functions
  const OSSL_PARAM *OP_keymgmt_importkey_types(void);
  const OSSL_PARAM *OP_keymgmt_exportkey_types(void);
 
+ /* Key information */
+ int OP_keymgmt_get_key_params(void *key, OSSL_PARAM params[]);
+ const OSSL_PARAM *OP_keymgmt_gettable_key_params(void);
+
  /* Discovery of supported operations */
  const char *OP_keymgmt_query_operation_name(int operation_id);
 
@@ -84,6 +92,9 @@ macros in L<openssl-core_numbers.h(7)>, as follows:
  OP_keymgmt_exportdomparams      OSSL_FUNC_KEYMGMT_EXPORTDOMPARAMS
  OP_keymgmt_importdomparam_types OSSL_FUNC_KEYMGMT_IMPORTDOMPARAM_TYPES
  OP_keymgmt_exportdomparam_types OSSL_FUNC_KEYMGMT_EXPORTDOMPARAM_TYPES
+ OP_keymgmt_get_domparam_params  OSSL_FUNC_KEYMGMT_GET_DOMPARAM_PARAMS
+ OP_keymgmt_gettable_domparam_params
+                                 OSSL_FUNC_KEYMGMT_GETTABLE_DOMPARAM_PARAMS
 
  OP_keymgmt_importkey            OSSL_FUNC_KEYMGMT_IMPORTKEY
  OP_keymgmt_genkey               OSSL_FUNC_KEYMGMT_GENKEY
@@ -92,6 +103,10 @@ macros in L<openssl-core_numbers.h(7)>, as follows:
  OP_keymgmt_exportkey            OSSL_FUNC_KEYMGMT_EXPORTKEY
  OP_keymgmt_importkey_types      OSSL_FUNC_KEYMGMT_IMPORTKEY_TYPES
  OP_keymgmt_exportkey_types      OSSL_FUNC_KEYMGMT_EXPORTKEY_TYPES
+ OP_keymgmt_get_key_params       OSSL_FUNC_KEYMGMT_GET_KEY_PARAMS
+ OP_keymgmt_gettable_key_params  OSSL_FUNC_KEYMGMT_GETTABLE_KEY_PARAMS
+
+ OP_keymgmt_query_operation_name OSSL_FUNC_KEYMGMT_QUERY_OPERATION_NAME
 
 =head2 Domain Parameter Functions
 
@@ -116,13 +131,18 @@ OP_keymgmt_importdomparam_types() should return a constant array of
 descriptor B<OSSL_PARAM>, for parameters that OP_keymgmt_importdomparams()
 can handle.
 
-=for comment There should be one corresponding to OP_keymgmt_gendomparams()
-as well...
-
 OP_keymgmt_exportdomparam_types() should return a constant array of
 descriptor B<OSSL_PARAM>, for parameters that can be exported with
 OP_keymgmt_exportdomparams().
 
+OP_keymgmt_get_domparam_params() should extract information data
+associated with the given I<domparams>,
+see L</Information Parameters>.
+
+OP_keymgmt_gettable_domparam_params() should return a constant array
+of descriptor B<OSSL_PARAM>, for parameters that
+OP_keymgmt_get_domparam_params() can handle.
+
 =head2 Key functions
 
 OP_keymgmt_importkey() should create a provider side structure
@@ -154,13 +174,17 @@ OP_keymgmt_importkey_types() should return a constant array of
 descriptor B<OSSL_PARAM>, for parameters that OP_keymgmt_importkey()
 can handle.
 
-=for comment There should be one corresponding to OP_keymgmt_genkey()
-as well...
-
 OP_keymgmt_exportkey_types() should return a constant array of
 descriptor B<OSSL_PARAM>, for parameters that can be exported with
 OP_keymgmt_exportkeys().
 
+OP_keymgmt_get_key_params() should extract information data associated
+with the given I<key>, see L</Information Parameters>.
+
+OP_keymgmt_gettable_key_params() should return a constant array of
+descriptor B<OSSL_PARAM>, for parameters that
+OP_keymgmt_get_key_params() can handle.
+
 =head2 Supported operations
 
 OP_keymgmt_query_operation_name() should return the name of the
@@ -171,6 +195,42 @@ returns NULL, the caller is free to assume that there's an algorithm
 from the same provider, of the same name as the one used to fetch the
 keymgmt and try to use that.
 
+=head2 Information Parameters
+
+See L<OSSL_PARAM(3)> for further details on the parameters structure.
+
+Parameters currently recognised by built-in keymgmt algorithms'
+OP_keymgmt_get_domparams_params() and OP_keymgmt_get_key_params()
+are:
+
+=over 4
+
+=item "bits" (B<OSSL_PKEY_PARAM_BITS>) <integer>
+
+The value should be the cryptographic length of the cryptosystem to
+which the key belongs, in bits.  The definition of cryptographic
+length is specific to the key cryptosystem.
+
+=item "max-size" (B<OSSL_PKEY_PARAM_MAX_SIZE>) <integer>
+
+The value should be the maximum size that a caller should allocate to
+safely store a signature (called I<sig> in L<provider-signature(7)>),
+the result of asymmmetric encryption / decryption (I<out> in
+L<provider-asym_cipher(7)>, a derived secret (I<secret> in
+L<provider-keyexch(7)>, and similar data).
+
+Because an EVP_KEYMGMT method is always tightly bound to another method
+(signature, asymmetric cipher, key exchange, ...) and must be of the
+same provider, this number only needs to be synchronised with the
+dimensions handled in the rest of the same provider.
+
+=item "security-bits" (B<OSSL_PKEY_PARAM_SECURITY_BITS>) <integer>
+
+The value should be the number of security bits of the given key.
+Bits of security is defined in SP800-57.
+
+=back
+
 =head1 SEE ALSO
 
 L<provider(7)>
index 91f535093ddfcc3252ef1eb5f623217931c8252b..b3d1f7d21ca9d8e52b1347114207c175132716b3 100644 (file)
@@ -565,6 +565,13 @@ struct evp_pkey_st {
      * a copy of that key's dirty count.
      */
     size_t dirty_cnt_copy;
+
+    /* Cache of domain parameter / key information */
+    struct {
+        int bits;
+        int security_bits;
+        int size;
+    } cache;
 } /* EVP_PKEY */ ;
 
 #define EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx) \
@@ -590,6 +597,8 @@ void evp_app_cleanup_int(void);
 void *evp_keymgmt_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt,
                                      int domainparams);
 void evp_keymgmt_clear_pkey_cache(EVP_PKEY *pk);
+void evp_keymgmt_cache_pkey(EVP_PKEY *pk, size_t index, EVP_KEYMGMT *keymgmt,
+                            void *provdata, int domainparams);
 void *evp_keymgmt_fromdata(EVP_PKEY *target, EVP_KEYMGMT *keymgmt,
                            const OSSL_PARAM params[], int domainparams);
 
@@ -608,6 +617,10 @@ const OSSL_PARAM *
 evp_keymgmt_importdomparam_types(const EVP_KEYMGMT *keymgmt);
 const OSSL_PARAM *
 evp_keymgmt_exportdomparam_types(const EVP_KEYMGMT *keymgmt);
+int evp_keymgmt_get_domparam_params(const EVP_KEYMGMT *keymgmt,
+                                    void *provdomparam, OSSL_PARAM params[]);
+const OSSL_PARAM *
+evp_keymgmt_gettable_domparam_params(const EVP_KEYMGMT *keymgmt);
 
 void *evp_keymgmt_importkey(const EVP_KEYMGMT *keymgmt,
                             const OSSL_PARAM params[]);
@@ -620,6 +633,9 @@ int evp_keymgmt_exportkey(const EVP_KEYMGMT *keymgmt, void *provkey,
                           OSSL_CALLBACK *param_cb, void *cbarg);
 const OSSL_PARAM *evp_keymgmt_importkey_types(const EVP_KEYMGMT *keymgmt);
 const OSSL_PARAM *evp_keymgmt_exportkey_types(const EVP_KEYMGMT *keymgmt);
+int evp_keymgmt_get_key_params(const EVP_KEYMGMT *keymgmt,
+                               void *provkey, OSSL_PARAM params[]);
+const OSSL_PARAM *evp_keymgmt_gettable_key_params(const EVP_KEYMGMT *keymgmt);
 
 /* Pulling defines out of C source files */
 
index 0bc51b35895e1112068369002b8b3d81f073b4b7..a347d967123a0d795596aaaf241f57c2fcb4de04 100644 (file)
@@ -154,6 +154,11 @@ extern "C" {
 #define OSSL_KDF_NAME_KRB5KDF       "KRB5KDF"
 
 /* PKEY parameters */
+/* Common PKEY parameters */
+#define OSSL_PKEY_PARAM_BITS                "bits" /* integer */
+#define OSSL_PKEY_PARAM_MAX_SIZE            "max-size" /* integer */
+#define OSSL_PKEY_PARAM_SECURITY_BITS       "security-bits" /* integer */
+
 /* Diffie-Hellman/DSA Parameters */
 #define OSSL_PKEY_PARAM_FFC_P        "p"
 #define OSSL_PKEY_PARAM_FFC_G        "g"
index f41f7c02d00aaed9b88cdfc48cf826b9209684a5..0a809ded154de9a60d96087a9a59dc2abe13f765 100644 (file)
@@ -371,6 +371,14 @@ OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, OP_keymgmt_importdomparam_types,
 OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, OP_keymgmt_exportdomparam_types,
                     (void))
 
+/* Key domain parameter information */
+#define OSSL_FUNC_KEYMGMT_GET_DOMPARAM_PARAMS       7
+#define OSSL_FUNC_KEYMGMT_GETTABLE_DOMPARAM_PARAMS  8
+OSSL_CORE_MAKE_FUNC(int, OP_keymgmt_get_domparam_params,
+                    (void *domparam, OSSL_PARAM params[]))
+OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, OP_keymgmt_gettable_domparam_params,
+                    (void))
+
 /* Key creation and destruction */
 # define OSSL_FUNC_KEYMGMT_IMPORTKEY               10
 # define OSSL_FUNC_KEYMGMT_GENKEY                  11
@@ -400,8 +408,15 @@ OSSL_CORE_MAKE_FUNC(int, OP_keymgmt_exportkey,
 OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, OP_keymgmt_importkey_types, (void))
 OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, OP_keymgmt_exportkey_types, (void))
 
+/* Key information */
+#define OSSL_FUNC_KEYMGMT_GET_KEY_PARAMS            17
+#define OSSL_FUNC_KEYMGMT_GETTABLE_KEY_PARAMS       18
+OSSL_CORE_MAKE_FUNC(int, OP_keymgmt_get_key_params,
+                    (void *key, OSSL_PARAM params[]))
+OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, OP_keymgmt_gettable_key_params, (void))
+
 /* Discovery of supported operations */
-# define OSSL_FUNC_KEYMGMT_QUERY_OPERATION_NAME    17
+# define OSSL_FUNC_KEYMGMT_QUERY_OPERATION_NAME     20
 OSSL_CORE_MAKE_FUNC(const char *,OP_keymgmt_query_operation_name,
                     (int operation_id))