]> www.wagner.pp.ru Git - openssl-gost/engine.git/blobdiff - gost_prov.c
Provider file - initial commit
[openssl-gost/engine.git] / gost_prov.c
diff --git a/gost_prov.c b/gost_prov.c
new file mode 100644 (file)
index 0000000..273703b
--- /dev/null
@@ -0,0 +1,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;
+}