Add an internal API to access the KEYMGMT provider functions
[openssl.git] / crypto / include / internal / evp_int.h
index f6f99edb142b69c281ad86c31644e71dc1b99294..50ed933926db4c4fd5bbd89ad61438525a6d6b10 100644 (file)
@@ -8,6 +8,7 @@
  */
 
 #include <openssl/evp.h>
+#include <openssl/core_numbers.h>
 #include "internal/refcount.h"
 
 /*
 #define EVP_MD_CTX_FLAG_KEEP_PKEY_CTX   0x0400
 
 struct evp_pkey_ctx_st {
+    EVP_KEYEXCH *exchange;
+    void *exchprovctx;
+
+    /* Legacy fields below */
+
     /* Method associated with this operation */
     const EVP_PKEY_METHOD *pmeth;
     /* Engine that implements this method or NULL if builtin */
@@ -117,7 +123,7 @@ typedef struct evp_mac_impl_st EVP_MAC_IMPL;
 struct evp_mac_st {
     int type;
     EVP_MAC_IMPL *(*new) (void);
-    int (*copy) (EVP_MAC_IMPL *macdst, EVP_MAC_IMPL *macsrc);
+    EVP_MAC_IMPL *(*dup) (const EVP_MAC_IMPL *macsrc);
     void (*free) (EVP_MAC_IMPL *macctx);
     size_t (*size) (EVP_MAC_IMPL *macctx);
     int (*init) (EVP_MAC_IMPL *macctx);
@@ -150,10 +156,11 @@ const EVP_MD *evp_keccak_kmac256(void);
  * object database.
  */
 int EVP_add_mac(const EVP_MAC *mac);
+int EVP_add_kdf(const EVP_KDF *kdf);
 
 /* struct evp_kdf_impl_st is defined by the implementation */
 typedef struct evp_kdf_impl_st EVP_KDF_IMPL;
-typedef struct {
+struct evp_kdf_st {
     int type;
     EVP_KDF_IMPL *(*new) (void);
     void (*free) (EVP_KDF_IMPL *impl);
@@ -162,17 +169,23 @@ typedef struct {
     int (*ctrl_str) (EVP_KDF_IMPL *impl, const char *type, const char *value);
     size_t (*size) (EVP_KDF_IMPL *impl);
     int (*derive) (EVP_KDF_IMPL *impl, unsigned char *key, size_t keylen);
-} EVP_KDF_METHOD;
+};
 
-extern const EVP_KDF_METHOD pbkdf2_kdf_meth;
-extern const EVP_KDF_METHOD scrypt_kdf_meth;
-extern const EVP_KDF_METHOD tls1_prf_kdf_meth;
-extern const EVP_KDF_METHOD hkdf_kdf_meth;
-extern const EVP_KDF_METHOD sshkdf_kdf_meth;
-extern const EVP_KDF_METHOD ss_kdf_meth;
+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;
+
+    /* Legacy structure members */
+    /* TODO(3.0): Remove these */
     int pkey_type;
     int md_size;
     unsigned long flags;
@@ -185,14 +198,36 @@ struct evp_md_st {
     int ctx_size;               /* how big does the ctx->md_data need to be */
     /* control function */
     int (*md_ctrl) (EVP_MD_CTX *ctx, int cmd, int p1, void *p2);
+
+    /* New structure members */
+    /* TODO(3.0): Remove above comment when legacy has gone */
+    OSSL_PROVIDER *prov;
+    CRYPTO_REF_COUNT refcnt;
+    CRYPTO_RWLOCK *lock;
+    OSSL_OP_digest_newctx_fn *newctx;
+    OSSL_OP_digest_init_fn *dinit;
+    OSSL_OP_digest_update_fn *dupdate;
+    OSSL_OP_digest_final_fn *dfinal;
+    OSSL_OP_digest_digest_fn *digest;
+    OSSL_OP_digest_freectx_fn *freectx;
+    OSSL_OP_digest_dupctx_fn *dupctx;
+    OSSL_OP_digest_size_fn *size;
+    OSSL_OP_digest_block_size_fn *dblock_size;
+    OSSL_OP_digest_set_params_fn *set_params;
+    OSSL_OP_digest_get_params_fn *get_params;
+
 } /* EVP_MD */ ;
 
 struct evp_cipher_st {
     int nid;
+
     int block_size;
     /* Default value for variable length ciphers */
     int key_len;
     int iv_len;
+
+    /* Legacy structure members */
+    /* TODO(3.0): Remove these */
     /* Various flags */
     unsigned long flags;
     /* init key */
@@ -213,6 +248,23 @@ struct evp_cipher_st {
     int (*ctrl) (EVP_CIPHER_CTX *, int type, int arg, void *ptr);
     /* Application data */
     void *app_data;
+
+    /* New structure members */
+    /* TODO(3.0): Remove above comment when legacy has gone */
+    OSSL_PROVIDER *prov;
+    CRYPTO_REF_COUNT refcnt;
+    CRYPTO_RWLOCK *lock;
+    OSSL_OP_cipher_newctx_fn *newctx;
+    OSSL_OP_cipher_encrypt_init_fn *einit;
+    OSSL_OP_cipher_decrypt_init_fn *dinit;
+    OSSL_OP_cipher_update_fn *cupdate;
+    OSSL_OP_cipher_final_fn *cfinal;
+    OSSL_OP_cipher_cipher_fn *ccipher;
+    OSSL_OP_cipher_freectx_fn *freectx;
+    OSSL_OP_cipher_dupctx_fn *dupctx;
+    OSSL_OP_cipher_get_params_fn *get_params;
+    OSSL_OP_cipher_ctx_get_params_fn *ctx_get_params;
+    OSSL_OP_cipher_ctx_set_params_fn *ctx_set_params;
 } /* EVP_CIPHER */ ;
 
 /* Macros to code block cipher wrappers */
@@ -452,9 +504,9 @@ typedef struct {
  * 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 */
@@ -474,18 +526,70 @@ struct evp_pkey_st {
         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];
+    /*
+     * If there is a legacy key assigned to this structure, we keep
+     * a copy of that key's dirty count.
+     */
+    size_t dirty_cnt_copy;
 } /* EVP_PKEY */ ;
 
 
 void openssl_add_all_ciphers_int(void);
 void openssl_add_all_digests_int(void);
 void openssl_add_all_macs_int(void);
+void openssl_add_all_kdfs_int(void);
 void evp_cleanup_int(void);
 void evp_app_cleanup_int(void);
 
+/* 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);
+
 /* Pulling defines out of C source files */
 
 #define EVP_RC4_KEY_SIZE 16