]> www.wagner.pp.ru Git - openssl-gost/engine.git/blob - gost_prov.c
MSVC: Add dllexport to OSSL_provider_init
[openssl-gost/engine.git] / gost_prov.c
1 /**********************************************************************
2  *                 gost_prov.c - The provider itself                  *
3  *                                                                    *
4  *      Copyright (c) 2021 Richard Levitte <richard@levitte.org>      *
5  *     This file is distributed under the same license as OpenSSL     *
6  *                                                                    *
7  *                Requires OpenSSL 3.0 for compilation                *
8  **********************************************************************/
9
10 #include <openssl/core_dispatch.h>
11 #include "gost_prov.h"
12 #include "gost_lcl.h"
13 #include "prov/err.h"           /* libprov err functions */
14
15 /*********************************************************************
16  *
17  *  Errors
18  *
19  *****/
20
21 /*
22  * Ugly hack, to get the errors generated by mkerr.pl.  This should ideally
23  * be replaced with a local OSSL_ITEM list of < number, string > pairs as
24  * reason strings, but for now, we will simply use GOST_str_reasons.
25  * Fortunately, the ERR_STRING_DATA structure is compatible with OSSL_ITEM,
26  * so we can return it directly.
27  */
28 static struct proverr_functions_st *err_handle;
29 #define GOST_PROV
30 #include "e_gost_err.c"
31 void ERR_GOST_error(int function, int reason, char *file, int line)
32 {
33     proverr_new_error(err_handle);
34     proverr_set_error_debug(err_handle, file, line, NULL);
35     proverr_set_error(err_handle, reason, NULL);
36 }
37
38 /*********************************************************************
39  *
40  *  Provider context
41  *
42  *****/
43
44 static void provider_ctx_free(PROV_CTX *ctx)
45 {
46     if (ctx != NULL) {
47         ENGINE_free(ctx->e);
48         proverr_free_handle(ctx->proverr_handle);
49         OSSL_LIB_CTX_free(ctx->libctx);
50     }
51     free(ctx);
52 }
53
54 extern int populate_gost_engine(ENGINE *e);
55 static PROV_CTX *provider_ctx_new(const OSSL_CORE_HANDLE *core,
56                                   const OSSL_DISPATCH *in)
57 {
58     PROV_CTX *ctx;
59
60     if ((ctx = malloc(sizeof(*ctx))) != NULL
61         && (ctx->proverr_handle = proverr_new_handle(core, in)) != NULL
62         && (ctx->libctx = OSSL_LIB_CTX_new()) != NULL
63         && (ctx->e = ENGINE_new()) != NULL
64         && populate_gost_engine(ctx->e)) {
65         ctx->core_handle = core;
66
67         /* Ugly hack */
68         err_handle = ctx->proverr_handle;
69     } else {
70         provider_ctx_free(ctx);
71         ctx = NULL;
72     }
73     return ctx;
74 }
75
76 /*********************************************************************
77  *
78  *  Setup
79  *
80  *****/
81
82 typedef void (*fptr_t)(void);
83
84 /* The function that returns the appropriate algorithm table per operation */
85 static const OSSL_ALGORITHM *gost_operation(void *vprovctx,
86                                                 int operation_id,
87                                                 const int *no_cache)
88 {
89     switch (operation_id) {
90     case OSSL_OP_CIPHER:
91         return GOST_prov_ciphers;
92     case OSSL_OP_DIGEST:
93         return GOST_prov_digests;
94     case OSSL_OP_MAC:
95         return GOST_prov_macs;
96     }
97     return NULL;
98 }
99
100 static int gost_get_params(void *provctx, OSSL_PARAM *params)
101 {
102     return 1;
103 }
104
105 static const OSSL_ITEM *gost_get_reason_strings(void *provctx)
106 {
107 #if 0
108     return reason_strings;
109 #endif
110     return (OSSL_ITEM *)GOST_str_reasons;
111 }
112
113 /* The function that tears down this provider */
114 static void gost_teardown(void *vprovctx)
115 {
116     GOST_prov_deinit_ciphers();
117     GOST_prov_deinit_digests();
118     GOST_prov_deinit_mac_digests();
119     provider_ctx_free(vprovctx);
120 }
121
122 /* The base dispatch table */
123 static const OSSL_DISPATCH provider_functions[] = {
124     { OSSL_FUNC_PROVIDER_QUERY_OPERATION, (fptr_t)gost_operation },
125     { OSSL_FUNC_PROVIDER_GET_REASON_STRINGS, (fptr_t)gost_get_reason_strings },
126     { OSSL_FUNC_PROVIDER_GET_PARAMS, (fptr_t)gost_get_params },
127     { OSSL_FUNC_PROVIDER_TEARDOWN, (fptr_t)gost_teardown },
128     { 0, NULL }
129 };
130
131 struct prov_ctx_st {
132     void *core_handle;
133     struct proverr_functions_st *err_handle;
134 };
135
136 #ifdef BUILDING_PROVIDER_AS_LIBRARY
137 /*
138  * This allows the provider to be built in library form.  In this case, the
139  * application must add it explicitly like this:
140  *
141  * OSSL_PROVIDER_add_builtin(NULL, "gost", GOST_provider_init);
142  */
143 # define OSSL_provider_init GOST_provider_init
144 #endif
145
146 OPENSSL_EXPORT
147 int OSSL_provider_init(const OSSL_CORE_HANDLE *core,
148                        const OSSL_DISPATCH *in,
149                        const OSSL_DISPATCH **out,
150                        void **vprovctx)
151 {
152     if ((*vprovctx = provider_ctx_new(core, in)) == NULL)
153         return 0;
154     *out = provider_functions;
155     return 1;
156 }