1/*
2 * Copyright 2006-2021 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 <stdio.h>
11#include <stdlib.h>
12#include <openssl/objects.h>
13#include <openssl/evp.h>
14#include "internal/cryptlib.h"
15#include "internal/provider.h"
16#include "internal/core.h"
17#include "crypto/evp.h"
18#include "evp_local.h"
19
20static int evp_pkey_asym_cipher_init(EVP_PKEY_CTX *ctx, int operation,
21                                     const OSSL_PARAM params[])
22{
23    int ret = 0;
24    void *provkey = NULL;
25    EVP_ASYM_CIPHER *cipher = NULL;
26    EVP_KEYMGMT *tmp_keymgmt = NULL;
27    const OSSL_PROVIDER *tmp_prov = NULL;
28    const char *supported_ciph = NULL;
29    int iter;
30
31    if (ctx == NULL) {
32        ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
33        return -2;
34    }
35
36    evp_pkey_ctx_free_old_ops(ctx);
37    ctx->operation = operation;
38
39    ERR_set_mark();
40
41    if (evp_pkey_ctx_is_legacy(ctx))
42        goto legacy;
43
44    if (ctx->pkey == NULL) {
45        ERR_clear_last_mark();
46        ERR_raise(ERR_LIB_EVP, EVP_R_NO_KEY_SET);
47        goto err;
48    }
49
50    /*
51     * Try to derive the supported asym cipher from |ctx->keymgmt|.
52     */
53    if (!ossl_assert(ctx->pkey->keymgmt == NULL
54                     || ctx->pkey->keymgmt == ctx->keymgmt)) {
55        ERR_clear_last_mark();
56        ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR);
57        goto err;
58    }
59    supported_ciph
60        = evp_keymgmt_util_query_operation_name(ctx->keymgmt,
61                                                OSSL_OP_ASYM_CIPHER);
62    if (supported_ciph == NULL) {
63        ERR_clear_last_mark();
64        ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
65        goto err;
66    }
67
68    /*
69     * We perform two iterations:
70     *
71     * 1.  Do the normal asym cipher fetch, using the fetching data given by
72     *     the EVP_PKEY_CTX.
73     * 2.  Do the provider specific asym cipher fetch, from the same provider
74     *     as |ctx->keymgmt|
75     *
76     * We then try to fetch the keymgmt from the same provider as the
77     * asym cipher, and try to export |ctx->pkey| to that keymgmt (when
78     * this keymgmt happens to be the same as |ctx->keymgmt|, the export
79     * is a no-op, but we call it anyway to not complicate the code even
80     * more).
81     * If the export call succeeds (returns a non-NULL provider key pointer),
82     * we're done and can perform the operation itself.  If not, we perform
83     * the second iteration, or jump to legacy.
84     */
85    for (iter = 1, provkey = NULL; iter < 3 && provkey == NULL; iter++) {
86        EVP_KEYMGMT *tmp_keymgmt_tofree;
87
88        /*
89         * If we're on the second iteration, free the results from the first.
90         * They are NULL on the first iteration, so no need to check what
91         * iteration we're on.
92         */
93        EVP_ASYM_CIPHER_free(cipher);
94        EVP_KEYMGMT_free(tmp_keymgmt);
95
96        switch (iter) {
97        case 1:
98            cipher = EVP_ASYM_CIPHER_fetch(ctx->libctx, supported_ciph,
99                                           ctx->propquery);
100            if (cipher != NULL)
101                tmp_prov = EVP_ASYM_CIPHER_get0_provider(cipher);
102            break;
103        case 2:
104            tmp_prov = EVP_KEYMGMT_get0_provider(ctx->keymgmt);
105            cipher =
106                evp_asym_cipher_fetch_from_prov((OSSL_PROVIDER *)tmp_prov,
107                                                supported_ciph, ctx->propquery);
108            if (cipher == NULL)
109                goto legacy;
110            break;
111        }
112        if (cipher == NULL)
113            continue;
114
115        /*
116         * Ensure that the key is provided, either natively, or as a cached
117         * export.  We start by fetching the keymgmt with the same name as
118         * |ctx->pkey|, but from the provider of the asym cipher method, using
119         * the same property query as when fetching the asym cipher method.
120         * With the keymgmt we found (if we did), we try to export |ctx->pkey|
121         * to it (evp_pkey_export_to_provider() is smart enough to only actually
122         * export it if |tmp_keymgmt| is different from |ctx->pkey|'s keymgmt)
123         */
124        tmp_keymgmt_tofree = tmp_keymgmt
125            = evp_keymgmt_fetch_from_prov((OSSL_PROVIDER *)tmp_prov,
126                                          EVP_KEYMGMT_get0_name(ctx->keymgmt),
127                                          ctx->propquery);
128        if (tmp_keymgmt != NULL)
129            provkey = evp_pkey_export_to_provider(ctx->pkey, ctx->libctx,
130                                                  &tmp_keymgmt, ctx->propquery);
131        if (tmp_keymgmt == NULL)
132            EVP_KEYMGMT_free(tmp_keymgmt_tofree);
133    }
134
135    if (provkey == NULL) {
136        EVP_ASYM_CIPHER_free(cipher);
137        goto legacy;
138    }
139
140    ERR_pop_to_mark();
141
142    /* No more legacy from here down to legacy: */
143
144    ctx->op.ciph.cipher = cipher;
145    ctx->op.ciph.algctx = cipher->newctx(ossl_provider_ctx(cipher->prov));
146    if (ctx->op.ciph.algctx == NULL) {
147        /* The provider key can stay in the cache */
148        ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
149        goto err;
150    }
151
152    switch (operation) {
153    case EVP_PKEY_OP_ENCRYPT:
154        if (cipher->encrypt_init == NULL) {
155            ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
156            ret = -2;
157            goto err;
158        }
159        ret = cipher->encrypt_init(ctx->op.ciph.algctx, provkey, params);
160        break;
161    case EVP_PKEY_OP_DECRYPT:
162        if (cipher->decrypt_init == NULL) {
163            ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
164            ret = -2;
165            goto err;
166        }
167        ret = cipher->decrypt_init(ctx->op.ciph.algctx, provkey, params);
168        break;
169    default:
170        ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
171        goto err;
172    }
173
174    if (ret <= 0)
175        goto err;
176    EVP_KEYMGMT_free(tmp_keymgmt);
177    return 1;
178
179 legacy:
180    /*
181     * If we don't have the full support we need with provided methods,
182     * let's go see if legacy does.
183     */
184    ERR_pop_to_mark();
185    EVP_KEYMGMT_free(tmp_keymgmt);
186    tmp_keymgmt = NULL;
187
188    if (ctx->pmeth == NULL || ctx->pmeth->encrypt == NULL) {
189        ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
190        return -2;
191    }
192    switch(ctx->operation) {
193    case EVP_PKEY_OP_ENCRYPT:
194        if (ctx->pmeth->encrypt_init == NULL)
195            return 1;
196        ret = ctx->pmeth->encrypt_init(ctx);
197        break;
198    case EVP_PKEY_OP_DECRYPT:
199        if (ctx->pmeth->decrypt_init == NULL)
200            return 1;
201        ret = ctx->pmeth->decrypt_init(ctx);
202        break;
203    default:
204        ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
205        ret = -1;
206    }
207
208 err:
209    if (ret <= 0) {
210        evp_pkey_ctx_free_old_ops(ctx);
211        ctx->operation = EVP_PKEY_OP_UNDEFINED;
212    }
213    EVP_KEYMGMT_free(tmp_keymgmt);
214    return ret;
215}
216
217int EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx)
218{
219    return evp_pkey_asym_cipher_init(ctx, EVP_PKEY_OP_ENCRYPT, NULL);
220}
221
222int EVP_PKEY_encrypt_init_ex(EVP_PKEY_CTX *ctx, const OSSL_PARAM params[])
223{
224    return evp_pkey_asym_cipher_init(ctx, EVP_PKEY_OP_ENCRYPT, params);
225}
226
227int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx,
228                     unsigned char *out, size_t *outlen,
229                     const unsigned char *in, size_t inlen)
230{
231    int ret;
232
233    if (ctx == NULL) {
234        ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
235        return -2;
236    }
237
238    if (ctx->operation != EVP_PKEY_OP_ENCRYPT) {
239        ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_INITIALIZED);
240        return -1;
241    }
242
243    if (ctx->op.ciph.algctx == NULL)
244        goto legacy;
245
246    ret = ctx->op.ciph.cipher->encrypt(ctx->op.ciph.algctx, out, outlen,
247                                       (out == NULL ? 0 : *outlen), in, inlen);
248    return ret;
249
250 legacy:
251    if (ctx->pmeth == NULL || ctx->pmeth->encrypt == NULL) {
252        ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
253        return -2;
254    }
255    M_check_autoarg(ctx, out, outlen, EVP_F_EVP_PKEY_ENCRYPT)
256        return ctx->pmeth->encrypt(ctx, out, outlen, in, inlen);
257}
258
259int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx)
260{
261    return evp_pkey_asym_cipher_init(ctx, EVP_PKEY_OP_DECRYPT, NULL);
262}
263
264int EVP_PKEY_decrypt_init_ex(EVP_PKEY_CTX *ctx, const OSSL_PARAM params[])
265{
266    return evp_pkey_asym_cipher_init(ctx, EVP_PKEY_OP_DECRYPT, params);
267}
268
269int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx,
270                     unsigned char *out, size_t *outlen,
271                     const unsigned char *in, size_t inlen)
272{
273    int ret;
274
275    if (ctx == NULL) {
276        ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
277        return -2;
278    }
279
280    if (ctx->operation != EVP_PKEY_OP_DECRYPT) {
281        ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_INITIALIZED);
282        return -1;
283    }
284
285    if (ctx->op.ciph.algctx == NULL)
286        goto legacy;
287
288    ret = ctx->op.ciph.cipher->decrypt(ctx->op.ciph.algctx, out, outlen,
289                                       (out == NULL ? 0 : *outlen), in, inlen);
290    return ret;
291
292 legacy:
293    if (ctx->pmeth == NULL || ctx->pmeth->decrypt == NULL) {
294        ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
295        return -2;
296    }
297    M_check_autoarg(ctx, out, outlen, EVP_F_EVP_PKEY_DECRYPT)
298        return ctx->pmeth->decrypt(ctx, out, outlen, in, inlen);
299}
300
301
302static EVP_ASYM_CIPHER *evp_asym_cipher_new(OSSL_PROVIDER *prov)
303{
304    EVP_ASYM_CIPHER *cipher = OPENSSL_zalloc(sizeof(EVP_ASYM_CIPHER));
305
306    if (cipher == NULL) {
307        ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
308        return NULL;
309    }
310
311    cipher->lock = CRYPTO_THREAD_lock_new();
312    if (cipher->lock == NULL) {
313        ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
314        OPENSSL_free(cipher);
315        return NULL;
316    }
317    cipher->prov = prov;
318    ossl_provider_up_ref(prov);
319    cipher->refcnt = 1;
320
321    return cipher;
322}
323
324static void *evp_asym_cipher_from_algorithm(int name_id,
325                                            const OSSL_ALGORITHM *algodef,
326                                            OSSL_PROVIDER *prov)
327{
328    const OSSL_DISPATCH *fns = algodef->implementation;
329    EVP_ASYM_CIPHER *cipher = NULL;
330    int ctxfncnt = 0, encfncnt = 0, decfncnt = 0;
331    int gparamfncnt = 0, sparamfncnt = 0;
332
333    if ((cipher = evp_asym_cipher_new(prov)) == NULL) {
334        ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
335        goto err;
336    }
337
338    cipher->name_id = name_id;
339    if ((cipher->type_name = ossl_algorithm_get1_first_name(algodef)) == NULL)
340        goto err;
341    cipher->description = algodef->algorithm_description;
342
343    for (; fns->function_id != 0; fns++) {
344        switch (fns->function_id) {
345        case OSSL_FUNC_ASYM_CIPHER_NEWCTX:
346            if (cipher->newctx != NULL)
347                break;
348            cipher->newctx = OSSL_FUNC_asym_cipher_newctx(fns);
349            ctxfncnt++;
350            break;
351        case OSSL_FUNC_ASYM_CIPHER_ENCRYPT_INIT:
352            if (cipher->encrypt_init != NULL)
353                break;
354            cipher->encrypt_init = OSSL_FUNC_asym_cipher_encrypt_init(fns);
355            encfncnt++;
356            break;
357        case OSSL_FUNC_ASYM_CIPHER_ENCRYPT:
358            if (cipher->encrypt != NULL)
359                break;
360            cipher->encrypt = OSSL_FUNC_asym_cipher_encrypt(fns);
361            encfncnt++;
362            break;
363        case OSSL_FUNC_ASYM_CIPHER_DECRYPT_INIT:
364            if (cipher->decrypt_init != NULL)
365                break;
366            cipher->decrypt_init = OSSL_FUNC_asym_cipher_decrypt_init(fns);
367            decfncnt++;
368            break;
369        case OSSL_FUNC_ASYM_CIPHER_DECRYPT:
370            if (cipher->decrypt != NULL)
371                break;
372            cipher->decrypt = OSSL_FUNC_asym_cipher_decrypt(fns);
373            decfncnt++;
374            break;
375        case OSSL_FUNC_ASYM_CIPHER_FREECTX:
376            if (cipher->freectx != NULL)
377                break;
378            cipher->freectx = OSSL_FUNC_asym_cipher_freectx(fns);
379            ctxfncnt++;
380            break;
381        case OSSL_FUNC_ASYM_CIPHER_DUPCTX:
382            if (cipher->dupctx != NULL)
383                break;
384            cipher->dupctx = OSSL_FUNC_asym_cipher_dupctx(fns);
385            break;
386        case OSSL_FUNC_ASYM_CIPHER_GET_CTX_PARAMS:
387            if (cipher->get_ctx_params != NULL)
388                break;
389            cipher->get_ctx_params
390                = OSSL_FUNC_asym_cipher_get_ctx_params(fns);
391            gparamfncnt++;
392            break;
393        case OSSL_FUNC_ASYM_CIPHER_GETTABLE_CTX_PARAMS:
394            if (cipher->gettable_ctx_params != NULL)
395                break;
396            cipher->gettable_ctx_params
397                = OSSL_FUNC_asym_cipher_gettable_ctx_params(fns);
398            gparamfncnt++;
399            break;
400        case OSSL_FUNC_ASYM_CIPHER_SET_CTX_PARAMS:
401            if (cipher->set_ctx_params != NULL)
402                break;
403            cipher->set_ctx_params
404                = OSSL_FUNC_asym_cipher_set_ctx_params(fns);
405            sparamfncnt++;
406            break;
407        case OSSL_FUNC_ASYM_CIPHER_SETTABLE_CTX_PARAMS:
408            if (cipher->settable_ctx_params != NULL)
409                break;
410            cipher->settable_ctx_params
411                = OSSL_FUNC_asym_cipher_settable_ctx_params(fns);
412            sparamfncnt++;
413            break;
414        }
415    }
416    if (ctxfncnt != 2
417        || (encfncnt != 0 && encfncnt != 2)
418        || (decfncnt != 0 && decfncnt != 2)
419        || (encfncnt != 2 && decfncnt != 2)
420        || (gparamfncnt != 0 && gparamfncnt != 2)
421        || (sparamfncnt != 0 && sparamfncnt != 2)) {
422        /*
423         * In order to be a consistent set of functions we must have at least
424         * a set of context functions (newctx and freectx) as well as a pair of
425         * "cipher" functions: (encrypt_init, encrypt) or
426         * (decrypt_init decrypt). set_ctx_params and settable_ctx_params are
427         * optional, but if one of them is present then the other one must also
428         * be present. The same applies to get_ctx_params and
429         * gettable_ctx_params. The dupctx function is optional.
430         */
431        ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS);
432        goto err;
433    }
434
435    return cipher;
436 err:
437    EVP_ASYM_CIPHER_free(cipher);
438    return NULL;
439}
440
441void EVP_ASYM_CIPHER_free(EVP_ASYM_CIPHER *cipher)
442{
443    int i;
444
445    if (cipher == NULL)
446        return;
447    CRYPTO_DOWN_REF(&cipher->refcnt, &i, cipher->lock);
448    if (i > 0)
449        return;
450    OPENSSL_free(cipher->type_name);
451    ossl_provider_free(cipher->prov);
452    CRYPTO_THREAD_lock_free(cipher->lock);
453    OPENSSL_free(cipher);
454}
455
456int EVP_ASYM_CIPHER_up_ref(EVP_ASYM_CIPHER *cipher)
457{
458    int ref = 0;
459
460    CRYPTO_UP_REF(&cipher->refcnt, &ref, cipher->lock);
461    return 1;
462}
463
464OSSL_PROVIDER *EVP_ASYM_CIPHER_get0_provider(const EVP_ASYM_CIPHER *cipher)
465{
466    return cipher->prov;
467}
468
469EVP_ASYM_CIPHER *EVP_ASYM_CIPHER_fetch(OSSL_LIB_CTX *ctx, const char *algorithm,
470                                       const char *properties)
471{
472    return evp_generic_fetch(ctx, OSSL_OP_ASYM_CIPHER, algorithm, properties,
473                             evp_asym_cipher_from_algorithm,
474                             (int (*)(void *))EVP_ASYM_CIPHER_up_ref,
475                             (void (*)(void *))EVP_ASYM_CIPHER_free);
476}
477
478EVP_ASYM_CIPHER *evp_asym_cipher_fetch_from_prov(OSSL_PROVIDER *prov,
479                                                 const char *algorithm,
480                                                 const char *properties)
481{
482    return evp_generic_fetch_from_prov(prov, OSSL_OP_ASYM_CIPHER,
483                                       algorithm, properties,
484                                       evp_asym_cipher_from_algorithm,
485                                       (int (*)(void *))EVP_ASYM_CIPHER_up_ref,
486                                       (void (*)(void *))EVP_ASYM_CIPHER_free);
487}
488
489int EVP_ASYM_CIPHER_is_a(const EVP_ASYM_CIPHER *cipher, const char *name)
490{
491    return evp_is_a(cipher->prov, cipher->name_id, NULL, name);
492}
493
494int evp_asym_cipher_get_number(const EVP_ASYM_CIPHER *cipher)
495{
496    return cipher->name_id;
497}
498
499const char *EVP_ASYM_CIPHER_get0_name(const EVP_ASYM_CIPHER *cipher)
500{
501    return cipher->type_name;
502}
503
504const char *EVP_ASYM_CIPHER_get0_description(const EVP_ASYM_CIPHER *cipher)
505{
506    return cipher->description;
507}
508
509void EVP_ASYM_CIPHER_do_all_provided(OSSL_LIB_CTX *libctx,
510                                     void (*fn)(EVP_ASYM_CIPHER *cipher,
511                                                void *arg),
512                                     void *arg)
513{
514    evp_generic_do_all(libctx, OSSL_OP_ASYM_CIPHER,
515                       (void (*)(void *, void *))fn, arg,
516                       evp_asym_cipher_from_algorithm,
517                       (int (*)(void *))EVP_ASYM_CIPHER_up_ref,
518                       (void (*)(void *))EVP_ASYM_CIPHER_free);
519}
520
521
522int EVP_ASYM_CIPHER_names_do_all(const EVP_ASYM_CIPHER *cipher,
523                                 void (*fn)(const char *name, void *data),
524                                 void *data)
525{
526    if (cipher->prov != NULL)
527        return evp_names_do_all(cipher->prov, cipher->name_id, fn, data);
528
529    return 1;
530}
531
532const OSSL_PARAM *EVP_ASYM_CIPHER_gettable_ctx_params(const EVP_ASYM_CIPHER *cip)
533{
534    void *provctx;
535
536    if (cip == NULL || cip->gettable_ctx_params == NULL)
537        return NULL;
538
539    provctx = ossl_provider_ctx(EVP_ASYM_CIPHER_get0_provider(cip));
540    return cip->gettable_ctx_params(NULL, provctx);
541}
542
543const OSSL_PARAM *EVP_ASYM_CIPHER_settable_ctx_params(const EVP_ASYM_CIPHER *cip)
544{
545    void *provctx;
546
547    if (cip == NULL || cip->settable_ctx_params == NULL)
548        return NULL;
549
550    provctx = ossl_provider_ctx(EVP_ASYM_CIPHER_get0_provider(cip));
551    return cip->settable_ctx_params(NULL, provctx);
552}
553