]> www.wagner.pp.ru Git - openssl-gost/engine.git/blob - gost_md.c
Merge branch 'master' of https://github.com/gost-engine/engine
[openssl-gost/engine.git] / gost_md.c
1 /**********************************************************************
2  *                          md_gost.c                                 *
3  *             Copyright (c) 2005-2006 Cryptocom LTD                  *
4  *             Copyright (c) 2020 Vitaly Chikunov <vt@altlinux.org>   *
5  *         This file is distributed under the same license as OpenSSL *
6  *                                                                    *
7  *       OpenSSL interface to GOST R 34.11-94 hash functions          *
8  *          Requires OpenSSL 0.9.9 for compilation                    *
9  **********************************************************************/
10 #include <string.h>
11 #include "gost_lcl.h"
12 #include "gosthash.h"
13 #include "e_gost_err.h"
14
15 /* implementation of GOST 34.11 hash function See gost_md.c*/
16 static int gost_digest_init(EVP_MD_CTX *ctx);
17 static int gost_digest_update(EVP_MD_CTX *ctx, const void *data,
18                               size_t count);
19 static int gost_digest_final(EVP_MD_CTX *ctx, unsigned char *md);
20 static int gost_digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from);
21 static int gost_digest_cleanup(EVP_MD_CTX *ctx);
22
23 GOST_digest GostR3411_94_digest = {
24     .nid = NID_id_GostR3411_94,
25     .result_size = 32,
26     .input_blocksize = 32,
27     .app_datasize = sizeof(struct ossl_gost_digest_ctx),
28     .init = gost_digest_init,
29     .update = gost_digest_update,
30     .final = gost_digest_final,
31     .copy = gost_digest_copy,
32     .cleanup = gost_digest_cleanup,
33 };
34
35 /*
36  * Single level template accessor.
37  * Note: that you cannot template 0 value.
38  */
39 #define TPL(st,field) ( \
40     ((st)->field) ?: TPL_VAL(st,field) \
41 )
42
43 #define TPL_VAL(st,field) ( \
44     ((st)->template ? (st)->template->field : 0) \
45 )
46
47 EVP_MD *GOST_init_digest(GOST_digest *d)
48 {
49     if (d->digest)
50         return d->digest;
51
52     EVP_MD *md;
53     if (!(md = EVP_MD_meth_new(d->nid, NID_undef))
54         || !EVP_MD_meth_set_result_size(md, TPL(d, result_size))
55         || !EVP_MD_meth_set_input_blocksize(md, TPL(d, input_blocksize))
56         || !EVP_MD_meth_set_app_datasize(md, TPL(d, app_datasize))
57         || !EVP_MD_meth_set_flags(md, d->flags | TPL_VAL(d, flags))
58         || !EVP_MD_meth_set_init(md, TPL(d, init))
59         || !EVP_MD_meth_set_update(md, TPL(d, update))
60         || !EVP_MD_meth_set_final(md, TPL(d, final))
61         || !EVP_MD_meth_set_copy(md, TPL(d, copy))
62         || !EVP_MD_meth_set_cleanup(md, TPL(d, cleanup))
63         || !EVP_MD_meth_set_ctrl(md, TPL(d, ctrl))) {
64         EVP_MD_meth_free(md);
65         md = NULL;
66     }
67     if (md && d->alias)
68         EVP_add_digest_alias(EVP_MD_name(md), d->alias);
69     d->digest = md;
70     return md;
71 }
72
73 void GOST_deinit_digest(GOST_digest *d)
74 {
75     if (d->alias)
76         EVP_delete_digest_alias(d->alias);
77     EVP_MD_meth_free(d->digest);
78     d->digest = NULL;
79 }
80
81 static int gost_digest_init(EVP_MD_CTX *ctx)
82 {
83     struct ossl_gost_digest_ctx *c = EVP_MD_CTX_md_data(ctx);
84     memset(&(c->dctx), 0, sizeof(gost_hash_ctx));
85     gost_init(&(c->cctx), &GostR3411_94_CryptoProParamSet);
86     c->dctx.cipher_ctx = &(c->cctx);
87     return 1;
88 }
89
90 static int gost_digest_update(EVP_MD_CTX *ctx, const void *data, size_t count)
91 {
92     return hash_block((gost_hash_ctx *) EVP_MD_CTX_md_data(ctx), data, count);
93 }
94
95 static int gost_digest_final(EVP_MD_CTX *ctx, unsigned char *md)
96 {
97     return finish_hash((gost_hash_ctx *) EVP_MD_CTX_md_data(ctx), md);
98
99 }
100
101 static int gost_digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from)
102 {
103     struct ossl_gost_digest_ctx *md_ctx = EVP_MD_CTX_md_data(to);
104     if (EVP_MD_CTX_md_data(to) && EVP_MD_CTX_md_data(from)) {
105         memcpy(EVP_MD_CTX_md_data(to), EVP_MD_CTX_md_data(from),
106                sizeof(struct ossl_gost_digest_ctx));
107         md_ctx->dctx.cipher_ctx = &(md_ctx->cctx);
108     }
109     return 1;
110 }
111
112 static int gost_digest_cleanup(EVP_MD_CTX *ctx)
113 {
114     if (EVP_MD_CTX_md_data(ctx))
115         memset(EVP_MD_CTX_md_data(ctx), 0,
116                sizeof(struct ossl_gost_digest_ctx));
117     return 1;
118 }
119 /* vim: set expandtab cinoptions=\:0,l1,t0,g0,(0 sw=4 : */