diff options
-rw-r--r-- | crypto/evp/evp_local.h | 5 | ||||
-rw-r--r-- | crypto/evp/keymgmt_lib.c | 89 | ||||
-rw-r--r-- | crypto/evp/keymgmt_meth.c | 26 | ||||
-rw-r--r-- | crypto/evp/p_lib.c | 22 | ||||
-rw-r--r-- | doc/man7/provider-keymgmt.pod | 72 | ||||
-rw-r--r-- | include/crypto/evp.h | 16 | ||||
-rw-r--r-- | include/openssl/core_names.h | 5 | ||||
-rw-r--r-- | include/openssl/core_numbers.h | 17 |
8 files changed, 225 insertions, 27 deletions
diff --git a/crypto/evp/evp_local.h b/crypto/evp/evp_local.h index de73267c98..0feace2aa5 100644 --- a/crypto/evp/evp_local.h +++ b/crypto/evp/evp_local.h @@ -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 */ ; diff --git a/crypto/evp/keymgmt_lib.c b/crypto/evp/keymgmt_lib.c index 4163bca5bb..53610d3ef8 100644 --- a/crypto/evp/keymgmt_lib.c +++ b/crypto/evp/keymgmt_lib.c @@ -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(); +} diff --git a/crypto/evp/keymgmt_meth.c b/crypto/evp/keymgmt_meth.c index 03d1686cf3..ae1f10e6b3 100644 --- a/crypto/evp/keymgmt_meth.c +++ b/crypto/evp/keymgmt_meth.c @@ -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; diff --git a/crypto/evp/p_lib.c b/crypto/evp/p_lib.c index 5c11ce1b6a..2e0890cac5 100644 --- a/crypto/evp/p_lib.c +++ b/crypto/evp/p_lib.c @@ -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; } - diff --git a/doc/man7/provider-keymgmt.pod b/doc/man7/provider-keymgmt.pod index 1c868c5630..adc1978a36 100644 --- a/doc/man7/provider-keymgmt.pod +++ b/doc/man7/provider-keymgmt.pod @@ -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)> diff --git a/include/crypto/evp.h b/include/crypto/evp.h index 91f535093d..b3d1f7d21c 100644 --- a/include/crypto/evp.h +++ b/include/crypto/evp.h @@ -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 */ diff --git a/include/openssl/core_names.h b/include/openssl/core_names.h index 0bc51b3589..a347d96712 100644 --- a/include/openssl/core_names.h +++ b/include/openssl/core_names.h @@ -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" diff --git a/include/openssl/core_numbers.h b/include/openssl/core_numbers.h index f41f7c02d0..0a809ded15 100644 --- a/include/openssl/core_numbers.h +++ b/include/openssl/core_numbers.h @@ -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)) |