LIBS=../../libcrypto
-$COMMON=digest.c evp_enc.c evp_lib.c evp_fetch.c cmeth_lib.c evp_utils.c
+$COMMON=digest.c evp_enc.c evp_lib.c evp_fetch.c cmeth_lib.c keymgmt_meth.c \
+ evp_utils.c
SOURCE[../../libcrypto]=$COMMON\
encode.c evp_key.c evp_cnf.c \
e_des.c e_bf.c e_idea.c e_des3.c e_camellia.c\
EVP_KDF_IMPL *impl; /* Algorithm-specific data */
} /* EVP_KDF_CTX */ ;
+struct evp_keymgmt_st {
+ int id; /* libcrypto internal */
+
+ const char *name;
+ OSSL_PROVIDER *prov;
+ CRYPTO_REF_COUNT refcnt;
+ CRYPTO_RWLOCK *lock;
+
+ /* Domain parameter routines */
+ OSSL_OP_keymgmt_importdomparams_fn *importdomparams;
+ OSSL_OP_keymgmt_gendomparams_fn *gendomparams;
+ OSSL_OP_keymgmt_freedomparams_fn *freedomparams;
+ OSSL_OP_keymgmt_exportdomparams_fn *exportdomparams;
+ OSSL_OP_keymgmt_importdomparam_types_fn *importdomparam_types;
+ OSSL_OP_keymgmt_exportdomparam_types_fn *exportdomparam_types;
+
+ /* Key routines */
+ OSSL_OP_keymgmt_importkey_fn *importkey;
+ OSSL_OP_keymgmt_genkey_fn *genkey;
+ OSSL_OP_keymgmt_loadkey_fn *loadkey;
+ OSSL_OP_keymgmt_freekey_fn *freekey;
+ OSSL_OP_keymgmt_exportkey_fn *exportkey;
+ OSSL_OP_keymgmt_importkey_types_fn *importkey_types;
+ OSSL_OP_keymgmt_exportkey_types_fn *exportkey_types;
+} /* EVP_KEYMGMT */ ;
+
struct evp_keyexch_st {
OSSL_PROVIDER *prov;
CRYPTO_REF_COUNT refcnt;
OSSL_OP_keyexch_set_params_fn *set_params;
} /* EVP_KEYEXCH */;
-
int PKCS5_v2_PBKDF2_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass,
int passlen, ASN1_TYPE *param,
const EVP_CIPHER *c, const EVP_MD *md,
--- /dev/null
+/*
+ * Copyright 2019 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
+ */
+
+#include <openssl/crypto.h>
+#include <openssl/core_numbers.h>
+#include <openssl/evp.h>
+#include <openssl/err.h>
+#include "internal/provider.h"
+#include "internal/refcount.h"
+#include "internal/evp_int.h"
+#include "evp_locl.h"
+
+
+static void *keymgmt_new(void)
+{
+ EVP_KEYMGMT *keymgmt = NULL;
+
+ if ((keymgmt = OPENSSL_zalloc(sizeof(*keymgmt))) == NULL
+ || (keymgmt->lock = CRYPTO_THREAD_lock_new()) == NULL) {
+ EVP_KEYMGMT_free(keymgmt);
+ return NULL;
+ }
+
+ keymgmt->refcnt = 1;
+
+ return keymgmt;
+}
+
+static void *keymgmt_from_dispatch(const OSSL_DISPATCH *fns,
+ OSSL_PROVIDER *prov)
+{
+ EVP_KEYMGMT *keymgmt = NULL;
+
+ if ((keymgmt = keymgmt_new()) == NULL)
+ return NULL;
+
+ for (; fns->function_id != 0; fns++) {
+ switch (fns->function_id) {
+ case OSSL_FUNC_KEYMGMT_IMPORTDOMPARAMS:
+ if (keymgmt->importdomparams != NULL)
+ break;
+ keymgmt->importdomparams =
+ OSSL_get_OP_keymgmt_importdomparams(fns);
+ break;
+ case OSSL_FUNC_KEYMGMT_GENDOMPARAMS:
+ if (keymgmt->gendomparams != NULL)
+ break;
+ keymgmt->gendomparams = OSSL_get_OP_keymgmt_gendomparams(fns);
+ break;
+ case OSSL_FUNC_KEYMGMT_FREEDOMPARAMS:
+ if (keymgmt->freedomparams != NULL)
+ break;
+ keymgmt->freedomparams = OSSL_get_OP_keymgmt_freedomparams(fns);
+ break;
+ case OSSL_FUNC_KEYMGMT_EXPORTDOMPARAMS:
+ if (keymgmt->exportdomparams != NULL)
+ break;
+ keymgmt->exportdomparams =
+ OSSL_get_OP_keymgmt_exportdomparams(fns);
+ break;
+ case OSSL_FUNC_KEYMGMT_IMPORTDOMPARAM_TYPES:
+ if (keymgmt->importdomparam_types != NULL)
+ break;
+ keymgmt->importdomparam_types =
+ OSSL_get_OP_keymgmt_importdomparam_types(fns);
+ break;
+ case OSSL_FUNC_KEYMGMT_EXPORTDOMPARAM_TYPES:
+ if (keymgmt->exportdomparam_types != NULL)
+ break;
+ keymgmt->exportdomparam_types =
+ OSSL_get_OP_keymgmt_exportdomparam_types(fns);
+ break;
+ case OSSL_FUNC_KEYMGMT_IMPORTKEY:
+ if (keymgmt->importkey != NULL)
+ break;
+ keymgmt->importkey = OSSL_get_OP_keymgmt_importkey(fns);
+ break;
+ case OSSL_FUNC_KEYMGMT_GENKEY:
+ if (keymgmt->genkey != NULL)
+ break;
+ keymgmt->genkey = OSSL_get_OP_keymgmt_genkey(fns);
+ break;
+ case OSSL_FUNC_KEYMGMT_LOADKEY:
+ if (keymgmt->loadkey != NULL)
+ break;
+ keymgmt->loadkey = OSSL_get_OP_keymgmt_loadkey(fns);
+ break;
+ case OSSL_FUNC_KEYMGMT_FREEKEY:
+ if (keymgmt->freekey != NULL)
+ break;
+ keymgmt->freekey = OSSL_get_OP_keymgmt_freekey(fns);
+ break;
+ case OSSL_FUNC_KEYMGMT_EXPORTKEY:
+ if (keymgmt->exportkey != NULL)
+ break;
+ keymgmt->exportkey = OSSL_get_OP_keymgmt_exportkey(fns);
+ break;
+ case OSSL_FUNC_KEYMGMT_IMPORTKEY_TYPES:
+ if (keymgmt->importkey_types != NULL)
+ break;
+ keymgmt->importkey_types =
+ OSSL_get_OP_keymgmt_importkey_types(fns);
+ break;
+ case OSSL_FUNC_KEYMGMT_EXPORTKEY_TYPES:
+ if (keymgmt->exportkey_types != NULL)
+ break;
+ keymgmt->exportkey_types =
+ OSSL_get_OP_keymgmt_exportkey_types(fns);
+ break;
+ }
+ }
+ /*
+ * Try to check that the method is sensible.
+ * It makes no sense being able to free stuff if you can't create it.
+ * It makes no sense providing OSSL_PARAM descriptors for import and
+ * export if you can't import or export.
+ */
+ if ((keymgmt->freedomparams != NULL
+ && (keymgmt->importdomparams == NULL
+ && keymgmt->gendomparams == NULL))
+ || (keymgmt->freekey != NULL
+ && (keymgmt->importkey == NULL
+ && keymgmt->genkey == NULL
+ && keymgmt->loadkey == NULL))
+ || (keymgmt->importdomparam_types != NULL
+ && keymgmt->importdomparams == NULL)
+ || (keymgmt->exportdomparam_types != NULL
+ && keymgmt->exportdomparams == NULL)
+ || (keymgmt->importkey_types != NULL
+ && keymgmt->importkey == NULL)
+ || (keymgmt->exportkey_types != NULL
+ && keymgmt->exportkey == NULL)) {
+ EVP_KEYMGMT_free(keymgmt);
+ EVPerr(0, EVP_R_INVALID_PROVIDER_FUNCTIONS);
+ return NULL;
+ }
+ keymgmt->prov = prov;
+ if (prov != NULL)
+ ossl_provider_up_ref(prov);
+
+ return keymgmt;
+}
+
+EVP_KEYMGMT *EVP_KEYMGMT_fetch(OPENSSL_CTX *ctx, const char *algorithm,
+ const char *properties)
+{
+ EVP_KEYMGMT *keymgmt =
+ evp_generic_fetch(ctx, OSSL_OP_KEYMGMT, algorithm, properties,
+ keymgmt_from_dispatch,
+ (int (*)(void *))EVP_KEYMGMT_up_ref,
+ (void (*)(void *))EVP_KEYMGMT_free);
+
+ return keymgmt;
+}
+
+int EVP_KEYMGMT_up_ref(EVP_KEYMGMT *keymgmt)
+{
+ int ref = 0;
+
+ CRYPTO_UP_REF(&keymgmt->refcnt, &ref, keymgmt->lock);
+ return 1;
+}
+
+void EVP_KEYMGMT_free(EVP_KEYMGMT *keymgmt)
+{
+ int ref = 0;
+
+ if (keymgmt == NULL)
+ return;
+
+ CRYPTO_DOWN_REF(&keymgmt->refcnt, &ref, keymgmt->lock);
+ if (ref > 0)
+ return;
+ ossl_provider_free(keymgmt->prov);
+ CRYPTO_THREAD_lock_free(keymgmt->lock);
+ OPENSSL_free(keymgmt);
+}
+
+const OSSL_PROVIDER *EVP_KEYMGMT_provider(const EVP_KEYMGMT *keymgmt)
+{
+ return keymgmt->prov;
+}
+
* method, as in, can it do arbitrary encryption....
*/
struct evp_pkey_st {
+ /* == Legacy attributes == */
int type;
int save_type;
- CRYPTO_REF_COUNT references;
const EVP_PKEY_ASN1_METHOD *ameth;
ENGINE *engine;
ENGINE *pmeth_engine; /* If not NULL public key ENGINE to use */
ECX_KEY *ecx; /* X25519, X448, Ed25519, Ed448 */
# endif
} pkey;
- int save_parameters;
- STACK_OF(X509_ATTRIBUTE) *attributes; /* [ 0 ] */
+
+ /* == Common attributes == */
+ CRYPTO_REF_COUNT references;
CRYPTO_RWLOCK *lock;
+ STACK_OF(X509_ATTRIBUTE) *attributes; /* [ 0 ] */
+ int save_parameters;
+
+ /* == Provider attributes == */
+ /*
+ * To support transparent export/import between providers that
+ * support the methods for it, and still not having to do the
+ * export/import every time a key is used, we maintain a cache
+ * of imported key, indexed by provider address.
+ * pkeys[0] is *always* the "original" key.
+ */
+ struct {
+ EVP_KEYMGMT *keymgmt;
+ void *provkey;
+ } pkeys[10];
} /* EVP_PKEY */ ;
--- /dev/null
+=pod
+
+=head1 NAME
+
+EVP_KEYMGMT,
+EVP_KEYMGMT_fetch,
+EVP_KEYMGMT_up_ref,
+EVP_KEYMGMT_free,
+EVP_KEYMGMT_provider
+- EVP key management routines
+
+=head1 SYNOPSIS
+
+ #include <openssl/evp.h>
+
+ typedef struct evp_keymgmt_st EVP_KEYMGMT;
+
+ EVP_KEYMGMT *EVP_KEYMGMT_fetch(OPENSSL_CTX *ctx, const char *algorithm,
+ const char *properties);
+ int EVP_KEYMGMT_up_ref(EVP_KEYMGMT *keymgmt);
+ void EVP_KEYMGMT_free(EVP_KEYMGMT *keymgmt);
+ const OSSL_PROVIDER *EVP_KEYMGMT_provider(const EVP_KEYMGMT *keymgmt);
+
+=head1 DESCRIPTION
+
+B<EVP_KEYMGMT> is a method object that represents key management
+implementations for different cryptographic algorithms.
+This method object provides functionality to have providers import key
+material from the outside, as well as export key material to the
+outside.
+Most of the functionality can only be used internally and has no
+public interface, this object is simply passed into other functions
+when needed.
+
+EVP_KEYMGMT_fetch() looks for an algorithm within the provider that
+has been loaded into the B<OPENSSL_CTX> given by I<ctx>, having the
+name given by I<algorithm> and the properties given by I<properties>.
+
+EVP_KEYMGMT_up_ref() increments the reference count for the given
+B<EVP_KEYMGMT> I<keymgmt>.
+
+EVP_KEYMGMT_free() decrements the reference count for the given
+B<EVP_KEYMGMT> I<keymgmt>, and when the count reaches zero, frees it.
+
+EVP_KEYMGMT_provider() returns the provider that has this particular
+implementation.
+
+=head1 NOTES
+
+EVP_KEYMGMT_fetch() may be called implicitly by other fetching
+functions, using the same library context and properties.
+Any other API that uses keys will typically do this.
+
+=head1 RETURN VALUES
+
+EVP_KEYMGMT_fetch() returns a pointer to the key management
+implementation represented by an EVP_KEYMGMT object, or NULL on
+error.
+
+EVP_KEYMGMT_up_ref() returns 1 on success, or 0 on error.
+
+EVP_KEYMGMT_free() doesn't return any value.
+
+EVP_KEYMGMT_provider() returns a pointer to a provider object, or NULL
+on error.
+
+=head1 SEE ALSO
+
+L<EVP_MD_fetch(3)>, L<OPENSSL_CTX(3)>
+
+=head1 HISTORY
+
+The functions described here were added in OpenSSL 3.0.
+
+=head1 COPYRIGHT
+
+Copyright 2019 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
+L<https://www.openssl.org/source/license.html>.
+
+=cut
OSSL_CORE_MAKE_FUNC(int, OP_cipher_ctx_set_params, (void *cctx,
const OSSL_PARAM params[]))
+/*-
+ * Key management
+ *
+ * Key domain parameter references can be created in several manners:
+ * - by importing the domain parameter material via an OSSL_PARAM array.
+ * - by generating key domain parameters, given input via an OSSL_PARAM
+ * array.
+ *
+ * Key references can be created in several manners:
+ * - by importing the key material via an OSSL_PARAM array.
+ * - by generating a key, given optional domain parameters and
+ * additional keygen parameters.
+ * If domain parameters are given, they must have been generated using
+ * the domain parameter generator functions.
+ * If the domain parameters comes from a different provider, results
+ * are undefined.
+ * THE CALLER MUST ENSURE THAT CORRECT DOMAIN PARAMETERS ARE USED.
+ * - by loading an internal key, given a binary blob that forms an identity.
+ * THE CALLER MUST ENSURE THAT A CORRECT IDENTITY IS USED.
+ */
+
+# define OSSL_OP_KEYMGMT 10
+
+/* Key domain parameter creation and destruction */
+# define OSSL_FUNC_KEYMGMT_IMPORTDOMPARAMS 1
+# define OSSL_FUNC_KEYMGMT_GENDOMPARAMS 2
+# define OSSL_FUNC_KEYMGMT_FREEDOMPARAMS 3
+OSSL_CORE_MAKE_FUNC(void *, OP_keymgmt_importdomparams,
+ (void *provctx, const OSSL_PARAM params[]))
+OSSL_CORE_MAKE_FUNC(void *, OP_keymgmt_gendomparams,
+ (void *provctx, const OSSL_PARAM params[]))
+OSSL_CORE_MAKE_FUNC(void, OP_keymgmt_freedomparams, (void *domparams))
+
+/* Key domain parameter export */
+# define OSSL_FUNC_KEYMGMT_EXPORTDOMPARAMS 4
+OSSL_CORE_MAKE_FUNC(int, OP_keymgmt_exportdomparams,
+ (void *domparams, OSSL_PARAM params[]))
+
+/* Key domain parameter discovery */
+# define OSSL_FUNC_KEYMGMT_IMPORTDOMPARAM_TYPES 5
+# define OSSL_FUNC_KEYMGMT_EXPORTDOMPARAM_TYPES 6
+OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, OP_keymgmt_importdomparam_types,
+ (void))
+OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, OP_keymgmt_exportdomparam_types,
+ (void))
+
+/* Key creation and destruction */
+# define OSSL_FUNC_KEYMGMT_IMPORTKEY 10
+# define OSSL_FUNC_KEYMGMT_GENKEY 11
+# define OSSL_FUNC_KEYMGMT_LOADKEY 12
+# define OSSL_FUNC_KEYMGMT_FREEKEY 13
+OSSL_CORE_MAKE_FUNC(void *, OP_keymgmt_importkey,
+ (void *provctx, const OSSL_PARAM params[]))
+OSSL_CORE_MAKE_FUNC(void *, OP_keymgmt_genkey,
+ (void *provctx,
+ void *domparams, const OSSL_PARAM genkeyparams[]))
+OSSL_CORE_MAKE_FUNC(void *, OP_keymgmt_loadkey,
+ (void *provctx, void *id, size_t idlen))
+OSSL_CORE_MAKE_FUNC(void, OP_keymgmt_freekey, (void *key))
+
+/* Key export */
+# define OSSL_FUNC_KEYMGMT_EXPORTKEY 14
+OSSL_CORE_MAKE_FUNC(int, OP_keymgmt_exportkey,
+ (void *key, OSSL_PARAM params[]))
+
+/* Key discovery */
+# define OSSL_FUNC_KEYMGMT_IMPORTKEY_TYPES 15
+# define OSSL_FUNC_KEYMGMT_EXPORTKEY_TYPES 16
+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 Exchange */
-# define OSSL_OP_KEYEXCH 3
+# define OSSL_OP_KEYEXCH 11
# define OSSL_FUNC_KEYEXCH_NEWCTX 1
# define OSSL_FUNC_KEYEXCH_INIT 2
size_t EVP_PKEY_meth_get_count(void);
const EVP_PKEY_METHOD *EVP_PKEY_meth_get0(size_t idx);
+EVP_KEYMGMT *EVP_KEYMGMT_fetch(OPENSSL_CTX *ctx, const char *algorithm,
+ const char *properties);
+int EVP_KEYMGMT_up_ref(EVP_KEYMGMT *keymgmt);
+void EVP_KEYMGMT_free(EVP_KEYMGMT *keymgmt);
+const OSSL_PROVIDER *EVP_KEYMGMT_provider(const EVP_KEYMGMT *keymgmt);
+
EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e);
EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e);
EVP_PKEY_CTX *EVP_PKEY_CTX_dup(const EVP_PKEY_CTX *ctx);
typedef struct evp_pkey_method_st EVP_PKEY_METHOD;
typedef struct evp_pkey_ctx_st EVP_PKEY_CTX;
+typedef struct evp_keymgmt_st EVP_KEYMGMT;
+
typedef struct evp_kdf_st EVP_KDF;
typedef struct evp_kdf_ctx_st EVP_KDF_CTX;
EVP_KEYEXCH_fetch 4791 3_0_0 EXIST::FUNCTION:
EVP_PKEY_CTX_set_dh_pad 4792 3_0_0 EXIST::FUNCTION:DH
EVP_PKEY_CTX_set_params 4793 3_0_0 EXIST::FUNCTION:
+EVP_KEYMGMT_fetch 4794 3_0_0 EXIST::FUNCTION:
+EVP_KEYMGMT_up_ref 4795 3_0_0 EXIST::FUNCTION:
+EVP_KEYMGMT_free 4796 3_0_0 EXIST::FUNCTION:
+EVP_KEYMGMT_provider 4797 3_0_0 EXIST::FUNCTION:
DTLS_timer_cb datatype
EVP_KDF datatype
EVP_KDF_CTX datatype
+EVP_KEYMGMT datatype
EVP_MAC datatype
EVP_MAC_CTX datatype
EVP_PKEY_gen_cb datatype