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