/********************************************************************** * gost_prov.c - The provider itself * * * * Copyright (c) 2021 Richard Levitte * * This file is distributed under the same license as OpenSSL * * * * Requires OpenSSL 3.0 for compilation * **********************************************************************/ #include #include #include "gost_prov.h" #include "gost_lcl.h" #include "prov/err.h" /* libprov err functions */ /********************************************************************* * * Errors * *****/ /* * Ugly hack, to get the errors generated by mkerr.pl. This should ideally * be replaced with a local OSSL_ITEM list of < number, string > pairs as * reason strings, but for now, we will simply use GOST_str_reasons. * Fortunately, the ERR_STRING_DATA structure is compatible with OSSL_ITEM, * so we can return it directly. */ static struct proverr_functions_st *err_handle; #define GOST_PROV #include "e_gost_err.c" void ERR_GOST_error(int function, int reason, char *file, int line) { proverr_new_error(err_handle); proverr_set_error_debug(err_handle, file, line, NULL); proverr_set_error(err_handle, reason, NULL); } /********************************************************************* * * Provider context * *****/ static void provider_ctx_free(PROV_CTX *ctx) { if (ctx != NULL) { ENGINE_free(ctx->e); proverr_free_handle(ctx->proverr_handle); OSSL_LIB_CTX_free(ctx->libctx); } OPENSSL_free(ctx); } extern int populate_gost_engine(ENGINE *e); static PROV_CTX *provider_ctx_new(const OSSL_CORE_HANDLE *core, const OSSL_DISPATCH *in) { PROV_CTX *ctx; if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) != NULL && (ctx->proverr_handle = proverr_new_handle(core, in)) != NULL && (ctx->libctx = OSSL_LIB_CTX_new()) != NULL && (ctx->e = ENGINE_new()) != NULL && populate_gost_engine(ctx->e)) { ctx->core_handle = core; /* Ugly hack */ err_handle = ctx->proverr_handle; } else { provider_ctx_free(ctx); ctx = NULL; } return ctx; } /********************************************************************* * * Setup * *****/ typedef void (*fptr_t)(void); /* The function that returns the appropriate algorithm table per operation */ static const OSSL_ALGORITHM *gost_operation(void *vprovctx, int operation_id, const int *no_cache) { switch (operation_id) { case OSSL_OP_CIPHER: return GOST_prov_ciphers; case OSSL_OP_DIGEST: return GOST_prov_digests; case OSSL_OP_MAC: return GOST_prov_macs; } return NULL; } static int gost_get_params(void *provctx, OSSL_PARAM *params) { OSSL_PARAM *p; p = OSSL_PARAM_locate(params, OSSL_PROV_PARAM_NAME); if (p != NULL && !OSSL_PARAM_set_utf8_ptr(p, "OpenSSL GOST Provider")) return 0; p = OSSL_PARAM_locate(params, OSSL_PROV_PARAM_STATUS); if (p != NULL && !OSSL_PARAM_set_int(p, 1)) /* We never fail. */ return 0; return 1; } static const OSSL_ITEM *gost_get_reason_strings(void *provctx) { #if 0 return reason_strings; #endif return (OSSL_ITEM *)GOST_str_reasons; } /* The function that tears down this provider */ static void gost_teardown(void *vprovctx) { GOST_prov_deinit_ciphers(); GOST_prov_deinit_digests(); GOST_prov_deinit_mac_digests(); provider_ctx_free(vprovctx); } /* The base dispatch table */ static const OSSL_DISPATCH provider_functions[] = { { OSSL_FUNC_PROVIDER_QUERY_OPERATION, (fptr_t)gost_operation }, { OSSL_FUNC_PROVIDER_GET_REASON_STRINGS, (fptr_t)gost_get_reason_strings }, { OSSL_FUNC_PROVIDER_GET_PARAMS, (fptr_t)gost_get_params }, { OSSL_FUNC_PROVIDER_TEARDOWN, (fptr_t)gost_teardown }, { 0, NULL } }; struct prov_ctx_st { void *core_handle; struct proverr_functions_st *err_handle; }; #ifdef BUILDING_PROVIDER_AS_LIBRARY /* * This allows the provider to be built in library form. In this case, the * application must add it explicitly like this: * * OSSL_PROVIDER_add_builtin(NULL, "gost", GOST_provider_init); */ # define OSSL_provider_init GOST_provider_init #endif OPENSSL_EXPORT int OSSL_provider_init(const OSSL_CORE_HANDLE *core, const OSSL_DISPATCH *in, const OSSL_DISPATCH **out, void **vprovctx) { if ((*vprovctx = provider_ctx_new(core, in)) == NULL) return 0; *out = provider_functions; return 1; }