Home | History | Annotate | Line # | Download | only in evp
      1 /*
      2  * Copyright 2025 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_dispatch.h>
     12 #include <openssl/evp.h>
     13 #include <openssl/err.h>
     14 #include "internal/core.h"
     15 #include "internal/provider.h"
     16 #include "internal/refcount.h"
     17 #include "crypto/evp.h"
     18 #include "evp_local.h"
     19 
     20 void *evp_skeymgmt_generate(const EVP_SKEYMGMT *skeymgmt, const OSSL_PARAM params[])
     21 {
     22     void *provctx = ossl_provider_ctx(EVP_SKEYMGMT_get0_provider(skeymgmt));
     23 
     24     return (skeymgmt->generate != NULL) ? skeymgmt->generate(provctx, params) : NULL;
     25 }
     26 
     27 void *evp_skeymgmt_import(const EVP_SKEYMGMT *skeymgmt, int selection, const OSSL_PARAM params[])
     28 {
     29     void *provctx = ossl_provider_ctx(EVP_SKEYMGMT_get0_provider(skeymgmt));
     30 
     31     /* This is mandatory, no need to check for its presence */
     32     return skeymgmt->import(provctx, selection, params);
     33 }
     34 
     35 int evp_skeymgmt_export(const EVP_SKEYMGMT *skeymgmt, void *keydata,
     36     int selection, OSSL_CALLBACK *param_cb, void *cbarg)
     37 {
     38     /* This is mandatory, no need to check for its presence */
     39     return skeymgmt->export(keydata, selection, param_cb, cbarg);
     40 }
     41 
     42 void evp_skeymgmt_freedata(const EVP_SKEYMGMT *skeymgmt, void *keydata)
     43 {
     44     /* This is mandatory, no need to check for its presence */
     45     skeymgmt->free(keydata);
     46 }
     47 
     48 static void *skeymgmt_new(void)
     49 {
     50     EVP_SKEYMGMT *skeymgmt = NULL;
     51 
     52     if ((skeymgmt = OPENSSL_zalloc(sizeof(*skeymgmt))) == NULL)
     53         return NULL;
     54     if (!CRYPTO_NEW_REF(&skeymgmt->refcnt, 1)) {
     55         EVP_SKEYMGMT_free(skeymgmt);
     56         return NULL;
     57     }
     58     return skeymgmt;
     59 }
     60 
     61 static void *skeymgmt_from_algorithm(int name_id,
     62     const OSSL_ALGORITHM *algodef,
     63     OSSL_PROVIDER *prov)
     64 {
     65     const OSSL_DISPATCH *fns = algodef->implementation;
     66     EVP_SKEYMGMT *skeymgmt = NULL;
     67 
     68     if ((skeymgmt = skeymgmt_new()) == NULL)
     69         return NULL;
     70 
     71     skeymgmt->name_id = name_id;
     72     if ((skeymgmt->type_name = ossl_algorithm_get1_first_name(algodef)) == NULL) {
     73         EVP_SKEYMGMT_free(skeymgmt);
     74         return NULL;
     75     }
     76     skeymgmt->description = algodef->algorithm_description;
     77 
     78     for (; fns->function_id != 0; fns++) {
     79         switch (fns->function_id) {
     80         case OSSL_FUNC_SKEYMGMT_FREE:
     81             if (skeymgmt->free == NULL)
     82                 skeymgmt->free = OSSL_FUNC_skeymgmt_free(fns);
     83             break;
     84         case OSSL_FUNC_SKEYMGMT_IMPORT:
     85             if (skeymgmt->import == NULL)
     86                 skeymgmt->import = OSSL_FUNC_skeymgmt_import(fns);
     87             break;
     88         case OSSL_FUNC_SKEYMGMT_EXPORT:
     89             if (skeymgmt->export == NULL)
     90                 skeymgmt->export = OSSL_FUNC_skeymgmt_export(fns);
     91             break;
     92         case OSSL_FUNC_SKEYMGMT_GENERATE:
     93             if (skeymgmt->generate == NULL)
     94                 skeymgmt->generate = OSSL_FUNC_skeymgmt_generate(fns);
     95             break;
     96         case OSSL_FUNC_SKEYMGMT_GET_KEY_ID:
     97             if (skeymgmt->get_key_id == NULL)
     98                 skeymgmt->get_key_id = OSSL_FUNC_skeymgmt_get_key_id(fns);
     99             break;
    100         case OSSL_FUNC_SKEYMGMT_IMP_SETTABLE_PARAMS:
    101             if (skeymgmt->imp_params == NULL)
    102                 skeymgmt->imp_params = OSSL_FUNC_skeymgmt_imp_settable_params(fns);
    103             break;
    104         case OSSL_FUNC_SKEYMGMT_GEN_SETTABLE_PARAMS:
    105             if (skeymgmt->gen_params == NULL)
    106                 skeymgmt->gen_params = OSSL_FUNC_skeymgmt_gen_settable_params(fns);
    107             break;
    108         }
    109     }
    110 
    111     /* Check that the provider is sensible */
    112     if (skeymgmt->free == NULL
    113         || skeymgmt->import == NULL
    114         || skeymgmt->export == NULL) {
    115         EVP_SKEYMGMT_free(skeymgmt);
    116         ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS);
    117         return NULL;
    118     }
    119 
    120     if (!ossl_provider_up_ref(prov)) {
    121         EVP_SKEYMGMT_free(skeymgmt);
    122         ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
    123         return NULL;
    124     }
    125     skeymgmt->prov = prov;
    126 
    127     return skeymgmt;
    128 }
    129 
    130 EVP_SKEYMGMT *evp_skeymgmt_fetch_from_prov(OSSL_PROVIDER *prov,
    131     const char *name,
    132     const char *properties)
    133 {
    134     return evp_generic_fetch_from_prov(prov,
    135         OSSL_OP_SKEYMGMT,
    136         name, properties,
    137         skeymgmt_from_algorithm,
    138         (int (*)(void *))EVP_SKEYMGMT_up_ref,
    139         (void (*)(void *))EVP_SKEYMGMT_free);
    140 }
    141 
    142 EVP_SKEYMGMT *EVP_SKEYMGMT_fetch(OSSL_LIB_CTX *ctx, const char *algorithm,
    143     const char *properties)
    144 {
    145     return evp_generic_fetch(ctx, OSSL_OP_SKEYMGMT, algorithm, properties,
    146         skeymgmt_from_algorithm,
    147         (int (*)(void *))EVP_SKEYMGMT_up_ref,
    148         (void (*)(void *))EVP_SKEYMGMT_free);
    149 }
    150 
    151 int EVP_SKEYMGMT_up_ref(EVP_SKEYMGMT *skeymgmt)
    152 {
    153     int ref = 0;
    154 
    155     CRYPTO_UP_REF(&skeymgmt->refcnt, &ref);
    156     return 1;
    157 }
    158 
    159 void EVP_SKEYMGMT_free(EVP_SKEYMGMT *skeymgmt)
    160 {
    161     int ref = 0;
    162 
    163     if (skeymgmt == NULL)
    164         return;
    165 
    166     CRYPTO_DOWN_REF(&skeymgmt->refcnt, &ref);
    167     if (ref > 0)
    168         return;
    169     OPENSSL_free(skeymgmt->type_name);
    170     ossl_provider_free(skeymgmt->prov);
    171     CRYPTO_FREE_REF(&skeymgmt->refcnt);
    172     OPENSSL_free(skeymgmt);
    173 }
    174 
    175 const OSSL_PROVIDER *EVP_SKEYMGMT_get0_provider(const EVP_SKEYMGMT *skeymgmt)
    176 {
    177     return (skeymgmt != NULL) ? skeymgmt->prov : NULL;
    178 }
    179 
    180 const char *EVP_SKEYMGMT_get0_description(const EVP_SKEYMGMT *skeymgmt)
    181 {
    182     return (skeymgmt != NULL) ? skeymgmt->description : NULL;
    183 }
    184 
    185 const char *EVP_SKEYMGMT_get0_name(const EVP_SKEYMGMT *skeymgmt)
    186 {
    187     return (skeymgmt != NULL) ? skeymgmt->type_name : NULL;
    188 }
    189 
    190 int EVP_SKEYMGMT_is_a(const EVP_SKEYMGMT *skeymgmt, const char *name)
    191 {
    192     return skeymgmt != NULL
    193         && evp_is_a(skeymgmt->prov, skeymgmt->name_id, NULL, name);
    194 }
    195 
    196 void EVP_SKEYMGMT_do_all_provided(OSSL_LIB_CTX *libctx,
    197     void (*fn)(EVP_SKEYMGMT *skeymgmt, void *arg),
    198     void *arg)
    199 {
    200     evp_generic_do_all(libctx, OSSL_OP_SKEYMGMT,
    201         (void (*)(void *, void *))fn, arg,
    202         skeymgmt_from_algorithm,
    203         (int (*)(void *))EVP_SKEYMGMT_up_ref,
    204         (void (*)(void *))EVP_SKEYMGMT_free);
    205 }
    206 
    207 int EVP_SKEYMGMT_names_do_all(const EVP_SKEYMGMT *skeymgmt,
    208     void (*fn)(const char *name, void *data),
    209     void *data)
    210 {
    211     if (skeymgmt == NULL)
    212         return 0;
    213 
    214     if (skeymgmt->prov != NULL)
    215         return evp_names_do_all(skeymgmt->prov, skeymgmt->name_id, fn, data);
    216 
    217     return 1;
    218 }
    219 
    220 const OSSL_PARAM *EVP_SKEYMGMT_get0_gen_settable_params(const EVP_SKEYMGMT *skeymgmt)
    221 {
    222     void *provctx = NULL;
    223 
    224     if (skeymgmt == NULL)
    225         return 0;
    226 
    227     provctx = ossl_provider_ctx(EVP_SKEYMGMT_get0_provider(skeymgmt));
    228 
    229     return (skeymgmt->gen_params != NULL) ? skeymgmt->gen_params(provctx) : NULL;
    230 }
    231 
    232 const OSSL_PARAM *EVP_SKEYMGMT_get0_imp_settable_params(const EVP_SKEYMGMT *skeymgmt)
    233 {
    234     void *provctx = NULL;
    235 
    236     if (skeymgmt == NULL)
    237         return 0;
    238 
    239     provctx = ossl_provider_ctx(EVP_SKEYMGMT_get0_provider(skeymgmt));
    240 
    241     return (skeymgmt->imp_params != NULL) ? skeymgmt->imp_params(provctx) : NULL;
    242 }
    243