Re-introduce legacy EVP_PKEY types for provided keys
[openssl.git] / include / crypto / evp.h
index 21f3f16053da82155268f105aa62e90d12a04f29..d1756cf183bea0c985e91e310af8ebab2a92550d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2015-2020 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
@@ -23,17 +23,19 @@ struct evp_pkey_ctx_st {
     int operation;
 
     /*
-     * Library context, Key type name and properties associated
-     * with this context
+     * Library context, property query, keytype and keymgmt associated with
+     * this context
      */
     OPENSSL_CTX *libctx;
-    const char *keytype;
     const char *propquery;
-
-    /* cached key manager */
+    const char *keytype;
     EVP_KEYMGMT *keymgmt;
 
     union {
+        struct {
+            void *genctx;
+        } keymgmt;
+
         struct {
             EVP_KEYEXCH *exchange;
             void *exchprovctx;
@@ -50,6 +52,14 @@ struct evp_pkey_ctx_st {
         } ciph;
     } op;
 
+    /* Application specific data, usually used by the callback */
+    void *app_data;
+    /* Keygen callback */
+    EVP_PKEY_gen_cb *pkey_gencb;
+    /* implementation specific keygen data */
+    int *keygen_info;
+    int keygen_info_count;
+
     /* Legacy fields below */
 
     /* Method associated with this operation */
@@ -62,13 +72,8 @@ struct evp_pkey_ctx_st {
     EVP_PKEY *peerkey;
     /* Algorithm specific data */
     void *data;
-    /* Application specific data */
-    void *app_data;
-    /* Keygen callback */
-    EVP_PKEY_gen_cb *pkey_gencb;
-    /* implementation specific keygen data */
-    int *keygen_info;
-    int keygen_info_count;
+    /* Indicator if digest_custom needs to be called */
+    unsigned int flag_call_digest_custom:1;
 } /* EVP_PKEY_CTX */ ;
 
 #define EVP_PKEY_FLAG_DYNAMIC   1
@@ -497,14 +502,47 @@ const EVP_CIPHER *EVP_##cname##_ecb(void) { return &cname##_ecb; }
                              cipher##_init_key, NULL, NULL, NULL, NULL)
 
 /*
- * Type needs to be a bit field Sub-type needs to be for variations on the
- * method, as in, can it do arbitrary encryption....
+ * An EVP_PKEY can have the following states:
+ *
+ * untyped & empty:
+ *
+ *     type == EVP_PKEY_NONE && keymgmt == NULL
+ *
+ * typed & empty:
+ *
+ *     (type != EVP_PKEY_NONE && pkey.ptr == NULL)      ## legacy (libcrypto only)
+ *     || (keymgmt != NULL && keydata == NULL)          ## provider side
+ *
+ * fully assigned:
+ *
+ *     (type != EVP_PKEY_NONE && pkey.ptr != NULL)      ## legacy (libcrypto only)
+ *     || (keymgmt != NULL && keydata != NULL)          ## provider side
+ *
+ * The easiest way to detect a legacy key is:
+ *
+ *     keymgmt == NULL && type != EVP_PKEY_NONE
+ *
+ * The easiest way to detect a provider side key is:
+ *
+ *     keymgmt != NULL
  */
+#define evp_pkey_is_blank(pk)                                   \
+    ((pk)->type == EVP_PKEY_NONE && (pk)->keymgmt == NULL)
+#define evp_pkey_is_typed(pk)                                   \
+    ((pk)->type != EVP_PKEY_NONE || (pk)->keymgmt != NULL)
+#define evp_pkey_is_assigned(pk)                                \
+    ((pk)->pkey.ptr != NULL || (pk)->keydata != NULL)
+#define evp_pkey_is_legacy(pk)                                  \
+    ((pk)->type != EVP_PKEY_NONE && (pk)->keymgmt == NULL)
+#define evp_pkey_is_provided(pk)                                \
+    ((pk)->keymgmt != NULL)
+
 struct evp_pkey_st {
     /* == Legacy attributes == */
     int type;
     int save_type;
 
+# ifndef FIPS_MODULE
     /*
      * 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.
@@ -514,26 +552,30 @@ struct evp_pkey_st {
     ENGINE *pmeth_engine; /* If not NULL public key ENGINE to use */
     union {
         void *ptr;
-# ifndef OPENSSL_NO_RSA
+#  ifndef OPENSSL_NO_RSA
         struct rsa_st *rsa;     /* RSA */
-# endif
-# ifndef OPENSSL_NO_DSA
+#  endif
+#  ifndef OPENSSL_NO_DSA
         struct dsa_st *dsa;     /* DSA */
-# endif
-# ifndef OPENSSL_NO_DH
+#  endif
+#  ifndef OPENSSL_NO_DH
         struct dh_st *dh;       /* DH */
-# endif
-# ifndef OPENSSL_NO_EC
+#  endif
+#  ifndef OPENSSL_NO_EC
         struct ec_key_st *ec;   /* ECC */
         ECX_KEY *ecx;           /* X25519, X448, Ed25519, Ed448 */
-# endif
+#  endif
     } pkey;
+# endif
 
     /* == Common attributes == */
     CRYPTO_REF_COUNT references;
     CRYPTO_RWLOCK *lock;
     STACK_OF(X509_ATTRIBUTE) *attributes; /* [ 0 ] */
     int save_parameters;
+#ifndef FIPS_MODULE
+    CRYPTO_EX_DATA ex_data;
+#endif
 
     /* == Provider attributes == */
 
@@ -596,6 +638,10 @@ struct evp_pkey_st {
     ((ctx)->operation == EVP_PKEY_OP_ENCRYPT \
      || (ctx)->operation == EVP_PKEY_OP_DECRYPT)
 
+#define EVP_PKEY_CTX_IS_GEN_OP(ctx) \
+    ((ctx)->operation == EVP_PKEY_OP_PARAMGEN \
+     || (ctx)->operation == EVP_PKEY_OP_KEYGEN)
+
 void openssl_add_all_ciphers_int(void);
 void openssl_add_all_digests_int(void);
 void evp_cleanup_int(void);
@@ -603,9 +649,10 @@ 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);
+#ifndef FIPS_MODULE
+int evp_pkey_downgrade(EVP_PKEY *pk);
+void evp_pkey_free_legacy(EVP_PKEY *x);
+#endif
 
 /*
  * KEYMGMT utility functions
@@ -621,7 +668,12 @@ void *evp_keymgmt_util_fromdata(EVP_PKEY *target, EVP_KEYMGMT *keymgmt,
                                 int selection, const OSSL_PARAM params[]);
 int evp_keymgmt_util_has(EVP_PKEY *pk, int selection);
 int evp_keymgmt_util_match(EVP_PKEY *pk1, EVP_PKEY *pk2, int selection);
-
+int evp_keymgmt_util_copy(EVP_PKEY *to, EVP_PKEY *from, int selection);
+void *evp_keymgmt_util_gen(EVP_PKEY *target, EVP_KEYMGMT *keymgmt,
+                           void *genctx, OSSL_CALLBACK *cb, void *cbarg);
+int evp_keymgmt_util_get_deflt_digest_name(EVP_KEYMGMT *keymgmt,
+                                           void *keydata,
+                                           char *mdname, size_t mdname_sz);
 
 /*
  * KEYMGMT provider interface functions
@@ -635,6 +687,16 @@ 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);
 
+void *evp_keymgmt_gen_init(const EVP_KEYMGMT *keymgmt, int selection);
+int evp_keymgmt_gen_set_template(const EVP_KEYMGMT *keymgmt, void *genctx,
+                                 void *template);
+int evp_keymgmt_gen_set_params(const EVP_KEYMGMT *keymgmt, void *genctx,
+                               const OSSL_PARAM params[]);
+const OSSL_PARAM *
+evp_keymgmt_gen_settable_params(const EVP_KEYMGMT *keymgmt);
+void *evp_keymgmt_gen(const EVP_KEYMGMT *keymgmt, void *genctx,
+                      OSSL_CALLBACK *cb, void *cbarg);
+void evp_keymgmt_gen_cleanup(const EVP_KEYMGMT *keymgmt, void *genctx);
 
 int evp_keymgmt_has(const EVP_KEYMGMT *keymgmt, void *keyddata, int selection);
 int evp_keymgmt_validate(const EVP_KEYMGMT *keymgmt, void *keydata,
@@ -673,7 +735,7 @@ void evp_encode_ctx_set_flags(EVP_ENCODE_CTX *ctx, unsigned int flags);
 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
+#ifndef FIPS_MODULE
 /*
  * Internal helpers for stricter EVP_PKEY_CTX_{set,get}_params().
  *
@@ -681,11 +743,14 @@ const EVP_MD *evp_get_digestbyname_ex(OPENSSL_CTX *libctx, const char *name);
  *
  * In particular they return -2 if any of the params is not supported.
  *
- * They are not available in FIPS_MODE as they depend on
+ * They are not available in FIPS_MODULE 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) */
+
+EVP_PKEY *evp_pkcs82pkey_int(const PKCS8_PRIV_KEY_INFO *p8, OPENSSL_CTX *libctx,
+                             const char *propq);
+#endif /* !defined(FIPS_MODULE) */