Skip to content

Commit 562e9ff

Browse files
committed
Introduce standalone gost_digest adaptor for provider
Add a new family of gost_digest* source files that implement an adaptor layer over gosthash and gosthash2012. This adaptor is used by gost_prov_digest and removes the dependency of gost_prov_digest on engine-specific code. In the future, the gost_digest* implementation may also replace gost_md/gost_md2012 in the engine backend.
1 parent 85b1e25 commit 562e9ff

18 files changed

Lines changed: 405 additions & 74 deletions

CMakeLists.txt

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ set(GOST_ERR_SOURCE_FILES
156156
e_gost_err.h
157157
)
158158

159-
set(GOST_CORE_SOURCE_FILES
159+
set(GOST_LEGACY_CORE_SOURCE_FILES
160160
gost_ameth.c
161161
gost_pmeth.c
162162
gost_ctl.c
@@ -174,6 +174,13 @@ set(GOST_CORE_SOURCE_FILES
174174
gost_keyexpimp.c
175175
)
176176

177+
set(GOST_NEW_CORE_DIGEST_SOURCE_FILES
178+
gost_digest_3411_2012.c
179+
gost_digest_3411_94.c
180+
gost_digest_base.c
181+
gost_digest.c
182+
)
183+
177184
set(GOST_EC_SOURCE_FILES
178185
gost_ec_keyx.c
179186
gost_ec_sign.c
@@ -193,7 +200,7 @@ set (GOST_OMAC_SOURCE_FILES
193200
)
194201

195202
set(GOST_LIB_SOURCE_FILES
196-
${GOST_CORE_SOURCE_FILES}
203+
${GOST_LEGACY_CORE_SOURCE_FILES}
197204
${GOST_GRASSHOPPER_SOURCE_FILES}
198205
${GOST_EC_SOURCE_FILES}
199206
${GOST_OMAC_SOURCE_FILES}
@@ -384,7 +391,7 @@ target_link_libraries(gost89 PRIVATE OpenSSL::Crypto)
384391

385392
add_library(gosthash STATIC ${GOST_HASH_SOURCE_FILES})
386393
set_target_properties(gosthash PROPERTIES POSITION_INDEPENDENT_CODE ON)
387-
target_link_libraries(gosthash PRIVATE OpenSSL::Crypto)
394+
target_link_libraries(gosthash PRIVATE OpenSSL::Crypto gost89)
388395

389396
add_library(gosthash2012 STATIC ${GOST_HASH_2012_SOURCE_FILES})
390397
set_target_properties(gosthash2012 PROPERTIES POSITION_INDEPENDENT_CODE ON)
@@ -398,6 +405,10 @@ add_library(gost_err STATIC ${GOST_ERR_SOURCE_FILES})
398405
set_target_properties(gost_err PROPERTIES POSITION_INDEPENDENT_CODE ON)
399406
target_link_libraries(gost_err PRIVATE OpenSSL::Crypto)
400407

408+
add_library(gost_new_core_digest STATIC ${GOST_NEW_CORE_DIGEST_SOURCE_FILES})
409+
set_target_properties(gost_new_core_digest PROPERTIES POSITION_INDEPENDENT_CODE ON)
410+
target_link_libraries(gost_new_core_digest PRIVATE OpenSSL::Crypto gosthash gosthash2012)
411+
401412
# The GOST engine in module form
402413
add_library(gost_engine MODULE ${GOST_ENGINE_SOURCE_FILES})
403414
# Set the suffix explicitly to adapt to OpenSSL's idea of what a
@@ -427,7 +438,7 @@ set_target_properties(gost_prov PROPERTIES
427438
PREFIX "" OUTPUT_NAME "gostprov" SUFFIX ${CMAKE_SHARED_LIBRARY_SUFFIX}
428439
COMPILE_DEFINITIONS "BUILDING_GOST_PROVIDER;OPENSSL_NO_DYNAMIC_ENGINE"
429440
)
430-
target_link_libraries(gost_prov PRIVATE gost_core libprov)
441+
target_link_libraries(gost_prov PRIVATE gost_core gost_new_core_digest libprov)
431442

432443
if (NOT MSVC)
433444
# The GOST provider in library form
@@ -438,7 +449,7 @@ set_target_properties(lib_gost_prov PROPERTIES
438449
OUTPUT_NAME "gostprov"
439450
COMPILE_DEFINITIONS "BUILDING_GOST_PROVIDER;BUILDING_PROVIDER_AS_LIBRARY;OPENSSL_NO_DYNAMIC_ENGINE"
440451
)
441-
target_link_libraries(lib_gost_prov PRIVATE gost_core libprov)
452+
target_link_libraries(lib_gost_prov PRIVATE gost_core gost_new_core_digest libprov)
442453
endif()
443454

444455
set(GOST_SUM_SOURCE_FILES

gost_digest.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#include "gost_digest.h"
2+
3+
void* GOST_digest_ctx_data(const GOST_digest_ctx* ctx) {
4+
return ctx->algctx;
5+
}

gost_digest.h

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
#pragma once
2+
3+
#include <stddef.h>
4+
#include <stdint.h>
5+
6+
#include "utils_one_level_inheritance.h"
7+
8+
struct gost_digest_st;
9+
typedef struct gost_digest_st GOST_digest;
10+
11+
struct gost_digest_ctx_st;
12+
typedef struct gost_digest_ctx_st GOST_digest_ctx;
13+
14+
typedef GOST_digest_ctx* (gost_digest_st_new_fn)(const GOST_digest *);
15+
typedef void (gost_digest_st_free_fn)(GOST_digest_ctx *);
16+
17+
typedef int (gost_digest_st_init_fn)(GOST_digest_ctx *ctx);
18+
typedef int (gost_digest_st_update_fn)(GOST_digest_ctx *ctx, const void *data, size_t count);
19+
typedef int (gost_digest_st_final_fn)(GOST_digest_ctx *ctx, unsigned char *md);
20+
typedef int (gost_digest_st_copy_fn)(GOST_digest_ctx *to, const GOST_digest_ctx *from);
21+
typedef int (gost_digest_st_cleanup_fn)(GOST_digest_ctx *ctx);
22+
typedef int (gost_digest_st_ctrl_fn)(GOST_digest_ctx *ctx, int cmd, int p1, void *p2);
23+
24+
typedef void (gost_digest_st_static_init_fn)(const GOST_digest *);
25+
typedef void (gost_digest_st_static_deinit_fn)(const GOST_digest *);
26+
27+
struct gost_digest_st {
28+
DECL_BASE(const struct gost_digest_st);
29+
30+
DECL_MEMBER(int, nid);
31+
DECL_MEMBER(const char *, alias);
32+
DECL_MEMBER(int, result_size);
33+
DECL_MEMBER(int, input_blocksize);
34+
DECL_MEMBER(int, flags);
35+
DECL_MEMBER(const char *, micalg);
36+
DECL_MEMBER(size_t, algctx_size);
37+
38+
DECL_MEMBER(gost_digest_st_new_fn *, new);
39+
DECL_MEMBER(gost_digest_st_free_fn *, free);
40+
DECL_MEMBER(gost_digest_st_init_fn *, init);
41+
DECL_MEMBER(gost_digest_st_update_fn *, update);
42+
DECL_MEMBER(gost_digest_st_final_fn *, final);
43+
DECL_MEMBER(gost_digest_st_copy_fn *, copy);
44+
DECL_MEMBER(gost_digest_st_cleanup_fn *, cleanup);
45+
DECL_MEMBER(gost_digest_st_ctrl_fn *, ctrl);
46+
47+
DECL_MEMBER(gost_digest_st_static_init_fn *, static_init);
48+
DECL_MEMBER(gost_digest_st_static_deinit_fn *, static_deinit);
49+
};
50+
51+
struct gost_digest_ctx_st {
52+
const GOST_digest* cls;
53+
void* algctx;
54+
};
55+
56+
void* GOST_digest_ctx_data(const GOST_digest_ctx* ctx);

gost_digest_3411_2012.c

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
#include <openssl/evp.h>
2+
#include <openssl/objects.h>
3+
#include "gosthash2012.h"
4+
#include "gost_digest_3411_2012.h"
5+
#include "gost_digest_base.h"
6+
7+
static int gost_digest_init(GOST_digest_ctx *ctx);
8+
static int gost_digest_update(GOST_digest_ctx *ctx, const void *data,
9+
size_t count);
10+
static int gost_digest_final(GOST_digest_ctx *ctx, unsigned char *md);
11+
static int gost_digest_copy(GOST_digest_ctx *to, const GOST_digest_ctx *from);
12+
static int gost_digest_cleanup(GOST_digest_ctx *ctx);
13+
14+
#define INIT_COMMON_MEMBERS() \
15+
INIT_MEMBER(base, &GostR3411_digest_base), \
16+
\
17+
INIT_MEMBER(input_blocksize, 64), \
18+
INIT_MEMBER(algctx_size, sizeof(gost2012_hash_ctx)), \
19+
\
20+
INIT_MEMBER(init, gost_digest_init), \
21+
INIT_MEMBER(update, gost_digest_update), \
22+
INIT_MEMBER(final, gost_digest_final), \
23+
INIT_MEMBER(copy, gost_digest_copy), \
24+
INIT_MEMBER(cleanup, gost_digest_cleanup)
25+
26+
const GOST_digest GostR3411_2012_256_digest = {
27+
INIT_MEMBER(nid, NID_id_GostR3411_2012_256),
28+
INIT_MEMBER(alias, "streebog256"),
29+
INIT_MEMBER(micalg, "gostr3411-2012-256"),
30+
INIT_MEMBER(result_size, 32),
31+
32+
INIT_COMMON_MEMBERS(),
33+
};
34+
35+
const GOST_digest GostR3411_2012_512_digest = {
36+
INIT_MEMBER(nid, NID_id_GostR3411_2012_512),
37+
INIT_MEMBER(alias, "streebog512"),
38+
INIT_MEMBER(micalg, "gostr3411-2012-512"),
39+
INIT_MEMBER(result_size, 64),
40+
41+
INIT_COMMON_MEMBERS(),
42+
};
43+
44+
static inline gost2012_hash_ctx* impl_digest_ctx_data(const GOST_digest_ctx *ctx) {
45+
return (gost2012_hash_ctx*)GOST_digest_ctx_data(ctx);
46+
}
47+
48+
static int gost_digest_init(GOST_digest_ctx *ctx)
49+
{
50+
init_gost2012_hash_ctx(impl_digest_ctx_data(ctx), 8 * GET_MEMBER(ctx->cls, result_size));
51+
return 1;
52+
}
53+
54+
static int gost_digest_update(GOST_digest_ctx *ctx, const void *data, size_t count)
55+
{
56+
gost2012_hash_block(impl_digest_ctx_data(ctx), data, count);
57+
return 1;
58+
}
59+
60+
static int gost_digest_final(GOST_digest_ctx *ctx, unsigned char *md)
61+
{
62+
gost2012_finish_hash(impl_digest_ctx_data(ctx), md);
63+
return 1;
64+
}
65+
66+
static int gost_digest_copy(GOST_digest_ctx *to, const GOST_digest_ctx *from)
67+
{
68+
memcpy(impl_digest_ctx_data(to), impl_digest_ctx_data(from), sizeof(gost2012_hash_ctx));
69+
70+
return 1;
71+
}
72+
73+
static int gost_digest_cleanup(GOST_digest_ctx *ctx)
74+
{
75+
OPENSSL_cleanse(impl_digest_ctx_data(ctx), sizeof(gost2012_hash_ctx));
76+
77+
return 1;
78+
}

gost_digest_3411_2012.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#pragma once
2+
3+
#include "gost_digest.h"
4+
5+
extern const GOST_digest GostR3411_2012_256_digest;
6+
extern const GOST_digest GostR3411_2012_512_digest;

gost_digest_3411_94.c

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
#include <string.h>
2+
3+
#include <openssl/objects.h>
4+
5+
#include "gost_digest_3411_94.h"
6+
#include "gost_digest_base.h"
7+
#include "gosthash.h"
8+
#include "gost89.h"
9+
10+
static int gost_digest_init(GOST_digest_ctx *ctx);
11+
static int gost_digest_update(GOST_digest_ctx *ctx, const void *data,
12+
size_t count);
13+
static int gost_digest_final(GOST_digest_ctx *ctx, unsigned char *md);
14+
static int gost_digest_copy(GOST_digest_ctx *to, const GOST_digest_ctx *from);
15+
static int gost_digest_cleanup(GOST_digest_ctx *ctx);
16+
17+
struct ossl_gost_digest_ctx {
18+
gost_hash_ctx dctx;
19+
gost_ctx cctx;
20+
};
21+
22+
static inline struct ossl_gost_digest_ctx* impl_digest_ctx_data(const GOST_digest_ctx *ctx) {
23+
return (struct ossl_gost_digest_ctx*)GOST_digest_ctx_data(ctx);
24+
}
25+
26+
const GOST_digest GostR3411_94_digest = {
27+
INIT_MEMBER(nid, NID_id_GostR3411_94),
28+
INIT_MEMBER(result_size, 32),
29+
INIT_MEMBER(input_blocksize, 32),
30+
INIT_MEMBER(algctx_size, sizeof(struct ossl_gost_digest_ctx)),
31+
32+
INIT_MEMBER(base, &GostR3411_digest_base),
33+
34+
INIT_MEMBER(init, gost_digest_init),
35+
INIT_MEMBER(update, gost_digest_update),
36+
INIT_MEMBER(final, gost_digest_final),
37+
INIT_MEMBER(copy, gost_digest_copy),
38+
INIT_MEMBER(cleanup, gost_digest_cleanup),
39+
};
40+
41+
static int gost_digest_init(GOST_digest_ctx *ctx)
42+
{
43+
struct ossl_gost_digest_ctx *c = impl_digest_ctx_data(ctx);
44+
memset(&(c->dctx), 0, sizeof(gost_hash_ctx));
45+
gost_init(&(c->cctx), &GostR3411_94_CryptoProParamSet);
46+
c->dctx.cipher_ctx = &(c->cctx);
47+
return 1;
48+
}
49+
50+
static int gost_digest_update(GOST_digest_ctx *ctx, const void *data, size_t count)
51+
{
52+
return hash_block(&(impl_digest_ctx_data(ctx)->dctx), data, count);
53+
}
54+
55+
static int gost_digest_final(GOST_digest_ctx *ctx, unsigned char *md)
56+
{
57+
return finish_hash(&(impl_digest_ctx_data(ctx)->dctx), md);
58+
}
59+
60+
static int gost_digest_copy(GOST_digest_ctx *to, const GOST_digest_ctx *from)
61+
{
62+
struct ossl_gost_digest_ctx *md_ctx = impl_digest_ctx_data(to);
63+
if (impl_digest_ctx_data(to) && impl_digest_ctx_data(from)) {
64+
memcpy(impl_digest_ctx_data(to), impl_digest_ctx_data(from),
65+
sizeof(struct ossl_gost_digest_ctx));
66+
md_ctx->dctx.cipher_ctx = &(md_ctx->cctx);
67+
}
68+
return 1;
69+
}
70+
71+
static int gost_digest_cleanup(GOST_digest_ctx *ctx)
72+
{
73+
if (impl_digest_ctx_data(ctx))
74+
OPENSSL_cleanse(impl_digest_ctx_data(ctx), sizeof(struct ossl_gost_digest_ctx));
75+
return 1;
76+
}

gost_digest_3411_94.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#pragma once
2+
3+
#include "gost_digest.h"
4+
5+
extern const GOST_digest GostR3411_94_digest;

gost_digest_base.c

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#include <openssl/evp.h>
2+
3+
#include "gost_digest_base.h"
4+
5+
static void gost_digest_static_init(const GOST_digest* d);
6+
static void gost_digest_static_deinit(const GOST_digest* d);
7+
8+
static GOST_digest_ctx* gost_digest_new(const GOST_digest* d);
9+
static void gost_digest_free(GOST_digest_ctx* vctx);
10+
11+
const GOST_digest GostR3411_digest_base = {
12+
INIT_MEMBER(static_init, gost_digest_static_init),
13+
INIT_MEMBER(static_deinit, gost_digest_static_deinit),
14+
INIT_MEMBER(new, gost_digest_new),
15+
INIT_MEMBER(free, gost_digest_free),
16+
};
17+
18+
static GOST_digest_ctx* gost_digest_new(const GOST_digest *d)
19+
{
20+
GOST_digest_ctx *ctx = (GOST_digest_ctx*)OPENSSL_zalloc(sizeof(GOST_digest_ctx));
21+
if (!ctx)
22+
return ctx;
23+
24+
ctx->cls = d;
25+
ctx->algctx = OPENSSL_zalloc(GET_MEMBER(d, algctx_size));
26+
if (!ctx->algctx) {
27+
OPENSSL_free(ctx);
28+
ctx = NULL;
29+
}
30+
31+
return ctx;
32+
}
33+
34+
void gost_digest_free(GOST_digest_ctx *ctx)
35+
{
36+
if (!ctx)
37+
return;
38+
39+
OPENSSL_free(ctx->algctx);
40+
OPENSSL_free(ctx);
41+
}
42+
43+
static void gost_digest_static_init(const GOST_digest* d) {
44+
if (GET_MEMBER(d, alias))
45+
EVP_add_digest_alias(OBJ_nid2sn(GET_MEMBER(d, nid)), GET_MEMBER(d, alias));
46+
}
47+
48+
static void gost_digest_static_deinit(const GOST_digest* d) {
49+
if (GET_MEMBER(d, alias))
50+
EVP_delete_digest_alias(GET_MEMBER(d, alias));
51+
}

gost_digest_base.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#pragma once
2+
3+
#include "gost_digest.h"
4+
5+
extern const GOST_digest GostR3411_digest_base;

gost_eng.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,10 +73,10 @@ static EVP_PKEY_ASN1_METHOD* ameth_GostR3410_2001 = NULL,
7373
* ameth_magma_mac_acpkm = NULL, * ameth_grasshopper_mac_acpkm = NULL;
7474

7575
GOST_digest *gost_digest_array[] = {
76-
&GostR3411_94_digest,
76+
&GostR3411_94_digest_legacy,
7777
&Gost28147_89_MAC_digest,
78-
&GostR3411_2012_256_digest,
79-
&GostR3411_2012_512_digest,
78+
&GostR3411_2012_256_digest_legacy,
79+
&GostR3411_2012_512_digest_legacy,
8080
&Gost28147_89_mac_12_digest,
8181
&magma_mac_digest,
8282
&grasshopper_mac_digest,

0 commit comments

Comments
 (0)