1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
|
#include <string.h>
#include <stdio.h>
#include <openssl/core.h>
#include <openssl/core_numbers.h>
#include <openssl/core_names.h>
#include <openssl/params.h>
#define GOST_PROV_VERSION_STR "3.0.0"
#define GOST_PROV_FULL_VERSION_STR "3.0.0"
/* Functions provided by the core */
static OSSL_core_gettable_params_fn *c_gettable_params = NULL;
static OSSL_core_get_params_fn *c_get_params = NULL;
/* Parameters we provide to the core */
static const OSSL_ITEM gost_param_types[] = {
{ OSSL_PARAM_UTF8_PTR, OSSL_PROV_PARAM_NAME },
{ OSSL_PARAM_UTF8_PTR, OSSL_PROV_PARAM_VERSION },
{ OSSL_PARAM_UTF8_PTR, OSSL_PROV_PARAM_BUILDINFO },
{ 0, NULL }
};
static const OSSL_ITEM *gost_gettable_params(const OSSL_PROVIDER *prov)
{
return gost_param_types;
}
static int gost_get_params(const OSSL_PROVIDER *prov, OSSL_PARAM params[])
{
OSSL_PARAM *p;
p = OSSL_PARAM_locate(params, OSSL_PROV_PARAM_NAME);
if (p != NULL && !OSSL_PARAM_set_utf8_ptr(p, "GOST Provider"))
return 0;
p = OSSL_PARAM_locate(params, OSSL_PROV_PARAM_VERSION);
if (p != NULL && !OSSL_PARAM_set_utf8_ptr(p, GOST_PROV_VERSION_STR))
return 0;
p = OSSL_PARAM_locate(params, OSSL_PROV_PARAM_BUILDINFO);
if (p != NULL && !OSSL_PARAM_set_utf8_ptr(p, GOST_PROV_FULL_VERSION_STR))
return 0;
return 1;
}
static const OSSL_ALGORITHM gost_digests[] = {
{ "md_gost94", "gost.legacy=yes", NULL }, /* FIXME */
{ "md_gost2012_256:streebog256", "gost.gost=yes", NULL },
{ "md_gost2012_512:streebog512", "gost.gost=yes", NULL },
{ NULL, NULL, NULL }
};
static const OSSL_ALGORITHM *gost_query(OSSL_PROVIDER *prov,
int operation_id,
int *no_cache)
{
*no_cache = 0;
switch (operation_id) {
case OSSL_OP_DIGEST:
return gost_digests;
}
return NULL;
}
/* Functions we provide to the core */
static const OSSL_DISPATCH gost_dispatch_table[] = {
{ OSSL_FUNC_PROVIDER_GETTABLE_PARAMS, (void (*)(void))gost_gettable_params },
{ OSSL_FUNC_PROVIDER_GET_PARAMS, (void (*)(void))gost_get_params },
{ OSSL_FUNC_PROVIDER_QUERY_OPERATION, (void (*)(void))gost_query },
{ 0, NULL }
};
int OSSL_provider_init(const OSSL_PROVIDER *provider,
const OSSL_DISPATCH *in,
const OSSL_DISPATCH **out,
void **provctx)
{
OSSL_core_get_library_context_fn *c_get_libctx = NULL;
for (; in->function_id != 0; in++) {
switch (in->function_id) {
case OSSL_FUNC_CORE_GETTABLE_PARAMS:
c_gettable_params = OSSL_get_core_gettable_params(in);
break;
case OSSL_FUNC_CORE_GET_PARAMS:
c_get_params = OSSL_get_core_get_params(in);
break;
case OSSL_FUNC_CORE_GET_LIBRARY_CONTEXT:
c_get_libctx = OSSL_get_core_get_library_context(in);
break;
/* Just ignore anything we don't understand */
default:
break;
}
}
if (c_get_libctx == NULL)
return 0;
*out = gost_dispatch_table;
/*
* We want to make sure that all calls from this provider that requires
* a library context use the same context as the one used to call our
* functions. We do that by passing it along as the provider context.
*/
*provctx = c_get_libctx(provider);
return 1;
}
|