#include <openssl/evp.h>
#include <openssl/core_numbers.h>
#include "internal/refcount.h"
+#include "crypto/ecx.h"
/*
* Don't free up md_ctx->pctx in EVP_MD_CTX_reset, use the reserved flag
/* Actual operation */
int operation;
+ /*
+ * Library context, Key type name and properties associated
+ * with this context
+ */
+ OPENSSL_CTX *libctx;
+ const char *keytype;
+ const char *propquery;
+
+ /* cached key manager */
+ EVP_KEYMGMT *keymgmt;
+
union {
struct {
EVP_KEYEXCH *exchange;
EVP_SIGNATURE *signature;
void *sigprovctx;
} sig;
+
+ struct {
+ EVP_ASYM_CIPHER *cipher;
+ void *ciphprovctx;
+ } ciph;
} op;
/* Legacy fields below */
OSSL_OP_kdf_set_ctx_params_fn *set_ctx_params;
};
-extern const EVP_KDF pbkdf2_kdf_meth;
-extern const EVP_KDF scrypt_kdf_meth;
-extern const EVP_KDF tls1_prf_kdf_meth;
-extern const EVP_KDF hkdf_kdf_meth;
-extern const EVP_KDF sshkdf_kdf_meth;
-extern const EVP_KDF ss_kdf_meth;
-extern const EVP_KDF x963_kdf_meth;
-extern const EVP_KDF x942_kdf_meth;
-
struct evp_md_st {
/* nid */
int type;
(fl)|EVP_CIPH_FLAG_DEFAULT_ASN1, \
cipher##_init_key, NULL, NULL, NULL, NULL)
-
-# ifndef OPENSSL_NO_EC
-
-#define X25519_KEYLEN 32
-#define X448_KEYLEN 56
-#define ED25519_KEYLEN 32
-#define ED448_KEYLEN 57
-
-#define MAX_KEYLEN ED448_KEYLEN
-
-typedef struct {
- unsigned char pubkey[MAX_KEYLEN];
- unsigned char *privkey;
-} ECX_KEY;
-
-#endif
-
/*
* Type needs to be a bit field Sub-type needs to be for variations on the
* method, as in, can it do arbitrary encryption....
/* == Legacy attributes == */
int type;
int save_type;
+
+ /*
+ * Legacy key "origin" is composed of a pointer to an EVP_PKEY_ASN1_METHOD,
+ * a pointer to a low level key and possibly a pointer to an engine.
+ */
const EVP_PKEY_ASN1_METHOD *ameth;
ENGINE *engine;
ENGINE *pmeth_engine; /* If not NULL public key ENGINE to use */
int save_parameters;
/* == Provider attributes == */
+
+ /*
+ * Provider keydata "origin" is composed of a pointer to an EVP_KEYMGMT
+ * and a pointer to the provider side key data. This is never used at
+ * the same time as the legacy key data above.
+ */
+ EVP_KEYMGMT *keymgmt;
+ void *keydata;
/*
- * 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.
+ * If any libcrypto code does anything that may modify the keydata
+ * contents, this dirty counter must be incremented.
+ */
+ size_t dirty_cnt;
+
+ /*
+ * To support transparent execution of operation in backends other
+ * than the "origin" key, we support transparent export/import to
+ * those providers, and maintain a cache of the imported keydata,
+ * so we don't need to redo the export/import every time we perform
+ * the same operation in that same provider.
+ * This requires that the "origin" backend (whether it's a legacy or a
+ * provider "origin") implements exports, and that the target provider
+ * has an EVP_KEYMGMT that implements import.
+ *
+ * The cache limit is set at 10 different providers using the same
+ * "origin". It's probably over the top, but is preferable to too
+ * few.
*/
struct {
EVP_KEYMGMT *keymgmt;
- void *provkey;
- } pkeys[10];
+ void *keydata;
+ } operation_cache[10];
/*
- * If there is a legacy key assigned to this structure, we keep
- * a copy of that key's dirty count.
+ * We keep a copy of that "origin"'s dirty count, so we know if the
+ * operation cache needs flushing.
*/
size_t dirty_cnt_copy;
+
+ /* Cache of key object information */
+ struct {
+ int bits;
+ int security_bits;
+ int size;
+ } cache;
} /* EVP_PKEY */ ;
#define EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx) \
#define EVP_PKEY_CTX_IS_DERIVE_OP(ctx) \
((ctx)->operation == EVP_PKEY_OP_DERIVE)
+#define EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx) \
+ ((ctx)->operation == EVP_PKEY_OP_ENCRYPT \
+ || (ctx)->operation == EVP_PKEY_OP_DECRYPT)
+
void openssl_add_all_ciphers_int(void);
void openssl_add_all_digests_int(void);
void evp_cleanup_int(void);
void evp_app_cleanup_int(void);
+void *evp_pkey_export_to_provider(EVP_PKEY *pk, OPENSSL_CTX *libctx,
+ EVP_KEYMGMT **keymgmt,
+ const char *propquery);
+void *evp_pkey_upgrade_to_provider(EVP_PKEY *pk, OPENSSL_CTX *libctx,
+ EVP_KEYMGMT **keymgmt,
+ const char *propquery);
+
+/*
+ * KEYMGMT utility functions
+ */
+void *evp_keymgmt_util_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt);
+size_t evp_keymgmt_util_find_operation_cache_index(EVP_PKEY *pk,
+ EVP_KEYMGMT *keymgmt);
+void evp_keymgmt_util_clear_operation_cache(EVP_PKEY *pk);
+int evp_keymgmt_util_cache_keydata(EVP_PKEY *pk, size_t index,
+ EVP_KEYMGMT *keymgmt, void *keydata);
+void evp_keymgmt_util_cache_keyinfo(EVP_PKEY *pk);
+void *evp_keymgmt_util_fromdata(EVP_PKEY *target, EVP_KEYMGMT *keymgmt,
+ int selection, const OSSL_PARAM params[]);
+
-/* KEYMGMT helper functions */
-void *evp_keymgmt_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt);
-void evp_keymgmt_clear_pkey_cache(EVP_PKEY *pk);
-
-/* KEYMGMT provider interface functions */
-void *evp_keymgmt_importdomparams(const EVP_KEYMGMT *keymgmt,
- const OSSL_PARAM params[]);
-void *evp_keymgmt_gendomparams(const EVP_KEYMGMT *keymgmt,
- const OSSL_PARAM params[]);
-void evp_keymgmt_freedomparams(const EVP_KEYMGMT *keymgmt,
- void *provdomparams);
-int evp_keymgmt_exportdomparams(const EVP_KEYMGMT *keymgmt,
- void *provdomparams, OSSL_PARAM params[]);
-const OSSL_PARAM *
-evp_keymgmt_importdomparam_types(const EVP_KEYMGMT *keymgmt);
-const OSSL_PARAM *
-evp_keymgmt_exportdomparam_types(const EVP_KEYMGMT *keymgmt);
-
-void *evp_keymgmt_importkey(const EVP_KEYMGMT *keymgmt,
- const OSSL_PARAM params[]);
-void *evp_keymgmt_genkey(const EVP_KEYMGMT *keymgmt, void *domparams,
- const OSSL_PARAM params[]);
-void *evp_keymgmt_loadkey(const EVP_KEYMGMT *keymgmt,
- void *id, size_t idlen);
-void evp_keymgmt_freekey(const EVP_KEYMGMT *keymgmt, void *provkey);
-int evp_keymgmt_exportkey(const EVP_KEYMGMT *keymgmt,
- void *provkey, OSSL_PARAM params[]);
-const OSSL_PARAM *evp_keymgmt_importkey_types(const EVP_KEYMGMT *keymgmt);
-const OSSL_PARAM *evp_keymgmt_exportkey_types(const EVP_KEYMGMT *keymgmt);
+/*
+ * KEYMGMT provider interface functions
+ */
+void *evp_keymgmt_newdata(const EVP_KEYMGMT *keymgmt);
+void evp_keymgmt_freedata(const EVP_KEYMGMT *keymgmt, void *keyddata);
+int evp_keymgmt_get_params(const EVP_KEYMGMT *keymgmt,
+ void *keydata, OSSL_PARAM params[]);
+const OSSL_PARAM *evp_keymgmt_gettable_params(const EVP_KEYMGMT *keymgmt);
+int evp_keymgmt_set_params(const EVP_KEYMGMT *keymgmt,
+ void *keydata, const OSSL_PARAM params[]);
+const OSSL_PARAM *evp_keymgmt_settable_params(const EVP_KEYMGMT *keymgmt);
+
+
+int evp_keymgmt_has(const EVP_KEYMGMT *keymgmt, void *keyddata, int selection);
+int evp_keymgmt_validate(const EVP_KEYMGMT *keymgmt, void *keydata,
+ int selection);
+
+int evp_keymgmt_import(const EVP_KEYMGMT *keymgmt, void *keydata,
+ int selection, const OSSL_PARAM params[]);
+const OSSL_PARAM *evp_keymgmt_import_types(const EVP_KEYMGMT *keymgmt,
+ int selection);
+int evp_keymgmt_export(const EVP_KEYMGMT *keymgmt, void *keydata,
+ int selection, OSSL_CALLBACK *param_cb, void *cbarg);
+const OSSL_PARAM *evp_keymgmt_export_types(const EVP_KEYMGMT *keymgmt,
+ int selection);
/* Pulling defines out of C source files */
#define EVP_ENCODE_CTX_NO_NEWLINES 1
/* Use the SRP base64 alphabet instead of the standard one */
#define EVP_ENCODE_CTX_USE_SRP_ALPHABET 2
+
+const EVP_CIPHER *evp_get_cipherbyname_ex(OPENSSL_CTX *libctx, const char *name);
+const EVP_MD *evp_get_digestbyname_ex(OPENSSL_CTX *libctx, const char *name);
+
+#ifndef FIPS_MODE
+/*
+ * Internal helpers for stricter EVP_PKEY_CTX_{set,get}_params().
+ *
+ * Return 1 on success, 0 or negative for errors.
+ *
+ * In particular they return -2 if any of the params is not supported.
+ *
+ * They are not available in FIPS_MODE as they depend on
+ * - EVP_PKEY_CTX_{get,set}_params()
+ * - EVP_PKEY_CTX_{gettable,settable}_params()
+ *
+ */
+int evp_pkey_ctx_set_params_strict(EVP_PKEY_CTX *ctx, OSSL_PARAM *params);
+int evp_pkey_ctx_get_params_strict(EVP_PKEY_CTX *ctx, OSSL_PARAM *params);
+#endif /* !defined(FIPS_MODE) */