Home | History | Annotate | Line # | Download | only in providers
      1 /*
      2  * Copyright 2019-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 <string.h>
     11 #include <stdio.h>
     12 #include <openssl/core.h>
     13 #include <openssl/core_dispatch.h>
     14 #include <openssl/core_names.h>
     15 #include <openssl/err.h>
     16 #include <openssl/params.h>
     17 #include "prov/provider_ctx.h"
     18 #include "prov/implementations.h"
     19 #include "prov/names.h"
     20 #include "prov/providercommon.h"
     21 
     22 /*
     23  * Forward declarations to ensure that interface functions are correctly
     24  * defined.
     25  */
     26 static OSSL_FUNC_provider_gettable_params_fn legacy_gettable_params;
     27 static OSSL_FUNC_provider_get_params_fn legacy_get_params;
     28 static OSSL_FUNC_provider_query_operation_fn legacy_query;
     29 
     30 #define ALG(NAMES, FUNC) { NAMES, "provider=legacy", FUNC }
     31 
     32 #ifdef STATIC_LEGACY
     33 OSSL_provider_init_fn ossl_legacy_provider_init;
     34 #define OSSL_provider_init ossl_legacy_provider_init
     35 #endif
     36 
     37 #ifndef STATIC_LEGACY
     38 /*
     39  * Should these function pointers be stored in the provider side provctx?
     40  * Could they ever be different from one init to the next? We assume not for
     41  * now.
     42  */
     43 
     44 /* Functions provided by the core */
     45 static OSSL_FUNC_core_new_error_fn *c_new_error;
     46 static OSSL_FUNC_core_set_error_debug_fn *c_set_error_debug;
     47 static OSSL_FUNC_core_vset_error_fn *c_vset_error;
     48 static OSSL_FUNC_core_set_error_mark_fn *c_set_error_mark;
     49 static OSSL_FUNC_core_clear_last_error_mark_fn *c_clear_last_error_mark;
     50 static OSSL_FUNC_core_pop_error_to_mark_fn *c_pop_error_to_mark;
     51 static OSSL_FUNC_core_count_to_mark_fn *c_count_to_mark;
     52 #endif
     53 
     54 /* Parameters we provide to the core */
     55 static const OSSL_PARAM legacy_param_types[] = {
     56     OSSL_PARAM_DEFN(OSSL_PROV_PARAM_NAME, OSSL_PARAM_UTF8_PTR, NULL, 0),
     57     OSSL_PARAM_DEFN(OSSL_PROV_PARAM_VERSION, OSSL_PARAM_UTF8_PTR, NULL, 0),
     58     OSSL_PARAM_DEFN(OSSL_PROV_PARAM_BUILDINFO, OSSL_PARAM_UTF8_PTR, NULL, 0),
     59     OSSL_PARAM_DEFN(OSSL_PROV_PARAM_STATUS, OSSL_PARAM_INTEGER, NULL, 0),
     60     OSSL_PARAM_END
     61 };
     62 
     63 static const OSSL_PARAM *legacy_gettable_params(void *provctx)
     64 {
     65     return legacy_param_types;
     66 }
     67 
     68 static int legacy_get_params(void *provctx, OSSL_PARAM params[])
     69 {
     70     OSSL_PARAM *p;
     71 
     72     p = OSSL_PARAM_locate(params, OSSL_PROV_PARAM_NAME);
     73     if (p != NULL && !OSSL_PARAM_set_utf8_ptr(p, "OpenSSL Legacy Provider"))
     74         return 0;
     75     p = OSSL_PARAM_locate(params, OSSL_PROV_PARAM_VERSION);
     76     if (p != NULL && !OSSL_PARAM_set_utf8_ptr(p, OPENSSL_VERSION_STR))
     77         return 0;
     78     p = OSSL_PARAM_locate(params, OSSL_PROV_PARAM_BUILDINFO);
     79     if (p != NULL && !OSSL_PARAM_set_utf8_ptr(p, OPENSSL_FULL_VERSION_STR))
     80         return 0;
     81     p = OSSL_PARAM_locate(params, OSSL_PROV_PARAM_STATUS);
     82     if (p != NULL && !OSSL_PARAM_set_int(p, ossl_prov_is_running()))
     83         return 0;
     84     return 1;
     85 }
     86 
     87 static const OSSL_ALGORITHM legacy_digests[] = {
     88 #ifndef OPENSSL_NO_MD2
     89     ALG(PROV_NAMES_MD2, ossl_md2_functions),
     90 #endif
     91 #ifndef OPENSSL_NO_MD4
     92     ALG(PROV_NAMES_MD4, ossl_md4_functions),
     93 #endif
     94 #ifndef OPENSSL_NO_MDC2
     95     ALG(PROV_NAMES_MDC2, ossl_mdc2_functions),
     96 #endif /* OPENSSL_NO_MDC2 */
     97 #ifndef OPENSSL_NO_WHIRLPOOL
     98     ALG(PROV_NAMES_WHIRLPOOL, ossl_wp_functions),
     99 #endif /* OPENSSL_NO_WHIRLPOOL */
    100 #ifndef OPENSSL_NO_RMD160
    101     ALG(PROV_NAMES_RIPEMD_160, ossl_ripemd160_functions),
    102 #endif /* OPENSSL_NO_RMD160 */
    103     { NULL, NULL, NULL }
    104 };
    105 
    106 static const OSSL_ALGORITHM legacy_ciphers[] = {
    107 #ifndef OPENSSL_NO_CAST
    108     ALG(PROV_NAMES_CAST5_ECB, ossl_cast5128ecb_functions),
    109     ALG(PROV_NAMES_CAST5_CBC, ossl_cast5128cbc_functions),
    110     ALG(PROV_NAMES_CAST5_OFB, ossl_cast5128ofb64_functions),
    111     ALG(PROV_NAMES_CAST5_CFB, ossl_cast5128cfb64_functions),
    112 #endif /* OPENSSL_NO_CAST */
    113 #ifndef OPENSSL_NO_BF
    114     ALG(PROV_NAMES_BF_ECB, ossl_blowfish128ecb_functions),
    115     ALG(PROV_NAMES_BF_CBC, ossl_blowfish128cbc_functions),
    116     ALG(PROV_NAMES_BF_OFB, ossl_blowfish128ofb64_functions),
    117     ALG(PROV_NAMES_BF_CFB, ossl_blowfish128cfb64_functions),
    118 #endif /* OPENSSL_NO_BF */
    119 #ifndef OPENSSL_NO_IDEA
    120     ALG(PROV_NAMES_IDEA_ECB, ossl_idea128ecb_functions),
    121     ALG(PROV_NAMES_IDEA_CBC, ossl_idea128cbc_functions),
    122     ALG(PROV_NAMES_IDEA_OFB, ossl_idea128ofb64_functions),
    123     ALG(PROV_NAMES_IDEA_CFB, ossl_idea128cfb64_functions),
    124 #endif /* OPENSSL_NO_IDEA */
    125 #ifndef OPENSSL_NO_SEED
    126     ALG(PROV_NAMES_SEED_ECB, ossl_seed128ecb_functions),
    127     ALG(PROV_NAMES_SEED_CBC, ossl_seed128cbc_functions),
    128     ALG(PROV_NAMES_SEED_OFB, ossl_seed128ofb128_functions),
    129     ALG(PROV_NAMES_SEED_CFB, ossl_seed128cfb128_functions),
    130 #endif /* OPENSSL_NO_SEED */
    131 #ifndef OPENSSL_NO_RC2
    132     ALG(PROV_NAMES_RC2_ECB, ossl_rc2128ecb_functions),
    133     ALG(PROV_NAMES_RC2_CBC, ossl_rc2128cbc_functions),
    134     ALG(PROV_NAMES_RC2_40_CBC, ossl_rc240cbc_functions),
    135     ALG(PROV_NAMES_RC2_64_CBC, ossl_rc264cbc_functions),
    136     ALG(PROV_NAMES_RC2_CFB, ossl_rc2128cfb128_functions),
    137     ALG(PROV_NAMES_RC2_OFB, ossl_rc2128ofb128_functions),
    138 #endif /* OPENSSL_NO_RC2 */
    139 #ifndef OPENSSL_NO_RC4
    140     ALG(PROV_NAMES_RC4, ossl_rc4128_functions),
    141     ALG(PROV_NAMES_RC4_40, ossl_rc440_functions),
    142 #ifndef OPENSSL_NO_MD5
    143     ALG(PROV_NAMES_RC4_HMAC_MD5, ossl_rc4_hmac_ossl_md5_functions),
    144 #endif /* OPENSSL_NO_MD5 */
    145 #endif /* OPENSSL_NO_RC4 */
    146 #ifndef OPENSSL_NO_RC5
    147     ALG(PROV_NAMES_RC5_ECB, ossl_rc5128ecb_functions),
    148     ALG(PROV_NAMES_RC5_CBC, ossl_rc5128cbc_functions),
    149     ALG(PROV_NAMES_RC5_OFB, ossl_rc5128ofb64_functions),
    150     ALG(PROV_NAMES_RC5_CFB, ossl_rc5128cfb64_functions),
    151 #endif /* OPENSSL_NO_RC5 */
    152 #ifndef OPENSSL_NO_DES
    153     ALG(PROV_NAMES_DESX_CBC, ossl_tdes_desx_cbc_functions),
    154     ALG(PROV_NAMES_DES_ECB, ossl_des_ecb_functions),
    155     ALG(PROV_NAMES_DES_CBC, ossl_des_cbc_functions),
    156     ALG(PROV_NAMES_DES_OFB, ossl_des_ofb64_functions),
    157     ALG(PROV_NAMES_DES_CFB, ossl_des_cfb64_functions),
    158     ALG(PROV_NAMES_DES_CFB1, ossl_des_cfb1_functions),
    159     ALG(PROV_NAMES_DES_CFB8, ossl_des_cfb8_functions),
    160 #endif /* OPENSSL_NO_DES */
    161     { NULL, NULL, NULL }
    162 };
    163 
    164 static const OSSL_ALGORITHM legacy_kdfs[] = {
    165     ALG(PROV_NAMES_PBKDF1, ossl_kdf_pbkdf1_functions),
    166     ALG(PROV_NAMES_PVKKDF, ossl_kdf_pvk_functions),
    167     { NULL, NULL, NULL }
    168 };
    169 
    170 static const OSSL_ALGORITHM *legacy_query(void *provctx, int operation_id,
    171     int *no_cache)
    172 {
    173     *no_cache = 0;
    174     switch (operation_id) {
    175     case OSSL_OP_DIGEST:
    176         return legacy_digests;
    177     case OSSL_OP_CIPHER:
    178         return legacy_ciphers;
    179     case OSSL_OP_KDF:
    180         return legacy_kdfs;
    181     }
    182     return NULL;
    183 }
    184 
    185 static void legacy_teardown(void *provctx)
    186 {
    187     OSSL_LIB_CTX_free(PROV_LIBCTX_OF(provctx));
    188     ossl_prov_ctx_free(provctx);
    189 }
    190 
    191 /* Functions we provide to the core */
    192 static const OSSL_DISPATCH legacy_dispatch_table[] = {
    193     { OSSL_FUNC_PROVIDER_TEARDOWN, (void (*)(void))legacy_teardown },
    194     { OSSL_FUNC_PROVIDER_GETTABLE_PARAMS, (void (*)(void))legacy_gettable_params },
    195     { OSSL_FUNC_PROVIDER_GET_PARAMS, (void (*)(void))legacy_get_params },
    196     { OSSL_FUNC_PROVIDER_QUERY_OPERATION, (void (*)(void))legacy_query },
    197     OSSL_DISPATCH_END
    198 };
    199 
    200 int OSSL_provider_init(const OSSL_CORE_HANDLE *handle,
    201     const OSSL_DISPATCH *in,
    202     const OSSL_DISPATCH **out,
    203     void **provctx)
    204 {
    205     OSSL_LIB_CTX *libctx = NULL;
    206 #ifndef STATIC_LEGACY
    207     const OSSL_DISPATCH *tmp;
    208 #endif
    209 
    210 #ifndef STATIC_LEGACY
    211     for (tmp = in; tmp->function_id != 0; tmp++) {
    212         /*
    213          * We do not support the scenario of an application linked against
    214          * multiple versions of libcrypto (e.g. one static and one dynamic),
    215          * but sharing a single legacy.so. We do a simple sanity check here.
    216          */
    217 #define set_func(c, f) \
    218     if (c == NULL)     \
    219         c = f;         \
    220     else if (c != f)   \
    221         return 0;
    222         switch (tmp->function_id) {
    223         case OSSL_FUNC_CORE_NEW_ERROR:
    224             set_func(c_new_error, OSSL_FUNC_core_new_error(tmp));
    225             break;
    226         case OSSL_FUNC_CORE_SET_ERROR_DEBUG:
    227             set_func(c_set_error_debug, OSSL_FUNC_core_set_error_debug(tmp));
    228             break;
    229         case OSSL_FUNC_CORE_VSET_ERROR:
    230             set_func(c_vset_error, OSSL_FUNC_core_vset_error(tmp));
    231             break;
    232         case OSSL_FUNC_CORE_SET_ERROR_MARK:
    233             set_func(c_set_error_mark, OSSL_FUNC_core_set_error_mark(tmp));
    234             break;
    235         case OSSL_FUNC_CORE_CLEAR_LAST_ERROR_MARK:
    236             set_func(c_clear_last_error_mark,
    237                 OSSL_FUNC_core_clear_last_error_mark(tmp));
    238             break;
    239         case OSSL_FUNC_CORE_POP_ERROR_TO_MARK:
    240             set_func(c_pop_error_to_mark, OSSL_FUNC_core_pop_error_to_mark(tmp));
    241             break;
    242         case OSSL_FUNC_CORE_COUNT_TO_MARK:
    243             set_func(c_count_to_mark, OSSL_FUNC_core_count_to_mark(in));
    244             break;
    245         }
    246     }
    247 #endif
    248 
    249     if ((*provctx = ossl_prov_ctx_new()) == NULL
    250         || (libctx = OSSL_LIB_CTX_new_child(handle, in)) == NULL) {
    251         OSSL_LIB_CTX_free(libctx);
    252         legacy_teardown(*provctx);
    253         *provctx = NULL;
    254         return 0;
    255     }
    256     ossl_prov_ctx_set0_libctx(*provctx, libctx);
    257     ossl_prov_ctx_set0_handle(*provctx, handle);
    258 
    259     *out = legacy_dispatch_table;
    260 
    261     return 1;
    262 }
    263 
    264 #ifndef STATIC_LEGACY
    265 /*
    266  * Provider specific implementation of libcrypto functions in terms of
    267  * upcalls.
    268  */
    269 
    270 /*
    271  * For ERR functions, we pass a NULL context.  This is valid to do as long
    272  * as only error codes that the calling libcrypto supports are used.
    273  */
    274 void ERR_new(void)
    275 {
    276     c_new_error(NULL);
    277 }
    278 
    279 void ERR_set_debug(const char *file, int line, const char *func)
    280 {
    281     c_set_error_debug(NULL, file, line, func);
    282 }
    283 
    284 void ERR_set_error(int lib, int reason, const char *fmt, ...)
    285 {
    286     va_list args;
    287 
    288     va_start(args, fmt);
    289     c_vset_error(NULL, ERR_PACK(lib, 0, reason), fmt, args);
    290     va_end(args);
    291 }
    292 
    293 void ERR_vset_error(int lib, int reason, const char *fmt, va_list args)
    294 {
    295     c_vset_error(NULL, ERR_PACK(lib, 0, reason), fmt, args);
    296 }
    297 
    298 int ERR_set_mark(void)
    299 {
    300     return c_set_error_mark(NULL);
    301 }
    302 
    303 int ERR_clear_last_mark(void)
    304 {
    305     return c_clear_last_error_mark(NULL);
    306 }
    307 
    308 int ERR_pop_to_mark(void)
    309 {
    310     return c_pop_error_to_mark(NULL);
    311 }
    312 
    313 int ERR_count_to_mark(void)
    314 {
    315     return c_count_to_mark != NULL ? c_count_to_mark(NULL) : 0;
    316 }
    317 #endif
    318