X-Git-Url: https://wagner.pp.ru/gitweb/?a=blobdiff_plain;f=gost_prov.c;fp=gost_prov.c;h=fe65c4d14a686e99e89620ebbd7944793475be69;hb=265d89dcbce7fce4fa2b560b70597132fd8eb3b2;hp=0000000000000000000000000000000000000000;hpb=23ccf9300e496e115742a44d5f52490f431156f5;p=openssl-gost%2Fengine.git diff --git a/gost_prov.c b/gost_prov.c new file mode 100644 index 0000000..fe65c4d --- /dev/null +++ b/gost_prov.c @@ -0,0 +1,144 @@ +/********************************************************************** + * 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 "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); + } + 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 = malloc(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) +{ + return NULL; +} + +static int gost_get_params(void *provctx, OSSL_PARAM *params) +{ + 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) +{ + 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 + +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; +}