Move Poly1305 to providers
[openssl.git] / crypto / evp / keymgmt_meth.c
1 /*
2  * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the Apache License 2.0 (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9
10 #include <openssl/crypto.h>
11 #include <openssl/core_numbers.h>
12 #include <openssl/evp.h>
13 #include <openssl/err.h>
14 #include "internal/provider.h"
15 #include "internal/refcount.h"
16 #include "internal/evp_int.h"
17 #include "evp_locl.h"
18
19
20 static void *keymgmt_new(void)
21 {
22     EVP_KEYMGMT *keymgmt = NULL;
23
24     if ((keymgmt = OPENSSL_zalloc(sizeof(*keymgmt))) == NULL
25         || (keymgmt->lock = CRYPTO_THREAD_lock_new()) == NULL) {
26         EVP_KEYMGMT_free(keymgmt);
27         EVPerr(0, ERR_R_MALLOC_FAILURE);
28         return NULL;
29     }
30
31     keymgmt->refcnt = 1;
32
33     return keymgmt;
34 }
35
36 static void *keymgmt_from_dispatch(const char *name, const OSSL_DISPATCH *fns,
37                                    OSSL_PROVIDER *prov)
38 {
39     EVP_KEYMGMT *keymgmt = NULL;
40
41     if ((keymgmt = keymgmt_new()) == NULL
42         || (keymgmt->name = OPENSSL_strdup(name)) == NULL) {
43         EVP_KEYMGMT_free(keymgmt);
44         return NULL;
45     }
46
47     for (; fns->function_id != 0; fns++) {
48         switch (fns->function_id) {
49         case OSSL_FUNC_KEYMGMT_IMPORTDOMPARAMS:
50             if (keymgmt->importdomparams != NULL)
51                 break;
52             keymgmt->importdomparams =
53                 OSSL_get_OP_keymgmt_importdomparams(fns);
54             break;
55         case OSSL_FUNC_KEYMGMT_GENDOMPARAMS:
56             if (keymgmt->gendomparams != NULL)
57                 break;
58             keymgmt->gendomparams = OSSL_get_OP_keymgmt_gendomparams(fns);
59             break;
60         case OSSL_FUNC_KEYMGMT_FREEDOMPARAMS:
61             if (keymgmt->freedomparams != NULL)
62                 break;
63             keymgmt->freedomparams = OSSL_get_OP_keymgmt_freedomparams(fns);
64             break;
65         case OSSL_FUNC_KEYMGMT_EXPORTDOMPARAMS:
66             if (keymgmt->exportdomparams != NULL)
67                 break;
68             keymgmt->exportdomparams =
69                 OSSL_get_OP_keymgmt_exportdomparams(fns);
70             break;
71         case OSSL_FUNC_KEYMGMT_IMPORTDOMPARAM_TYPES:
72             if (keymgmt->importdomparam_types != NULL)
73                 break;
74             keymgmt->importdomparam_types =
75                 OSSL_get_OP_keymgmt_importdomparam_types(fns);
76             break;
77         case OSSL_FUNC_KEYMGMT_EXPORTDOMPARAM_TYPES:
78             if (keymgmt->exportdomparam_types != NULL)
79                 break;
80             keymgmt->exportdomparam_types =
81                 OSSL_get_OP_keymgmt_exportdomparam_types(fns);
82             break;
83         case OSSL_FUNC_KEYMGMT_IMPORTKEY:
84             if (keymgmt->importkey != NULL)
85                 break;
86             keymgmt->importkey = OSSL_get_OP_keymgmt_importkey(fns);
87             break;
88         case OSSL_FUNC_KEYMGMT_GENKEY:
89             if (keymgmt->genkey != NULL)
90                 break;
91             keymgmt->genkey = OSSL_get_OP_keymgmt_genkey(fns);
92             break;
93         case OSSL_FUNC_KEYMGMT_LOADKEY:
94             if (keymgmt->loadkey != NULL)
95                 break;
96             keymgmt->loadkey = OSSL_get_OP_keymgmt_loadkey(fns);
97             break;
98         case OSSL_FUNC_KEYMGMT_FREEKEY:
99             if (keymgmt->freekey != NULL)
100                 break;
101             keymgmt->freekey = OSSL_get_OP_keymgmt_freekey(fns);
102             break;
103         case OSSL_FUNC_KEYMGMT_EXPORTKEY:
104             if (keymgmt->exportkey != NULL)
105                 break;
106             keymgmt->exportkey = OSSL_get_OP_keymgmt_exportkey(fns);
107             break;
108         case OSSL_FUNC_KEYMGMT_IMPORTKEY_TYPES:
109             if (keymgmt->importkey_types != NULL)
110                 break;
111             keymgmt->importkey_types =
112                 OSSL_get_OP_keymgmt_importkey_types(fns);
113             break;
114         case OSSL_FUNC_KEYMGMT_EXPORTKEY_TYPES:
115             if (keymgmt->exportkey_types != NULL)
116                 break;
117             keymgmt->exportkey_types =
118                 OSSL_get_OP_keymgmt_exportkey_types(fns);
119             break;
120         }
121     }
122     /*
123      * Try to check that the method is sensible.
124      * It makes no sense being able to free stuff if you can't create it.
125      * It makes no sense providing OSSL_PARAM descriptors for import and
126      * export if you can't import or export.
127      */
128     if ((keymgmt->freedomparams != NULL
129          && (keymgmt->importdomparams == NULL
130              && keymgmt->gendomparams == NULL))
131         || (keymgmt->freekey != NULL
132             && (keymgmt->importkey == NULL
133                 && keymgmt->genkey == NULL
134                 && keymgmt->loadkey == NULL))
135         || (keymgmt->importdomparam_types != NULL
136             && keymgmt->importdomparams == NULL)
137         || (keymgmt->exportdomparam_types != NULL
138             && keymgmt->exportdomparams == NULL)
139         || (keymgmt->importkey_types != NULL
140             && keymgmt->importkey == NULL)
141         || (keymgmt->exportkey_types != NULL
142             && keymgmt->exportkey == NULL)) {
143         EVP_KEYMGMT_free(keymgmt);
144         EVPerr(0, EVP_R_INVALID_PROVIDER_FUNCTIONS);
145         return NULL;
146     }
147     keymgmt->prov = prov;
148     if (prov != NULL)
149         ossl_provider_up_ref(prov);
150
151     return keymgmt;
152 }
153
154 EVP_KEYMGMT *EVP_KEYMGMT_fetch(OPENSSL_CTX *ctx, const char *algorithm,
155                                const char *properties)
156 {
157     EVP_KEYMGMT *keymgmt =
158         evp_generic_fetch(ctx, OSSL_OP_KEYMGMT, algorithm, properties,
159                           keymgmt_from_dispatch,
160                           (int (*)(void *))EVP_KEYMGMT_up_ref,
161                           (void (*)(void *))EVP_KEYMGMT_free);
162
163     return keymgmt;
164 }
165
166 int EVP_KEYMGMT_up_ref(EVP_KEYMGMT *keymgmt)
167 {
168     int ref = 0;
169
170     CRYPTO_UP_REF(&keymgmt->refcnt, &ref, keymgmt->lock);
171     return 1;
172 }
173
174 void EVP_KEYMGMT_free(EVP_KEYMGMT *keymgmt)
175 {
176     int ref = 0;
177
178     if (keymgmt == NULL)
179         return;
180
181     CRYPTO_DOWN_REF(&keymgmt->refcnt, &ref, keymgmt->lock);
182     if (ref > 0)
183         return;
184     ossl_provider_free(keymgmt->prov);
185     OPENSSL_free(keymgmt->name);
186     CRYPTO_THREAD_lock_free(keymgmt->lock);
187     OPENSSL_free(keymgmt);
188 }
189
190 const OSSL_PROVIDER *EVP_KEYMGMT_provider(const EVP_KEYMGMT *keymgmt)
191 {
192     return keymgmt->prov;
193 }
194