166 lines
4.8 KiB
C
166 lines
4.8 KiB
C
/**********************************************************************
|
|
* gost_prov.c - The provider itself *
|
|
* *
|
|
* Copyright (c) 2021 Richard Levitte <richard@levitte.org> *
|
|
* This file is distributed under the same license as OpenSSL *
|
|
* *
|
|
* Requires OpenSSL 3.0 for compilation *
|
|
**********************************************************************/
|
|
|
|
#include <openssl/core_dispatch.h>
|
|
#include <openssl/core_names.h>
|
|
#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;
|
|
}
|