]> www.wagner.pp.ru Git - openssl-gost/engine.git/blob - gost_md2012.c
9385b080c908c9df0426d76b1fdb65f719206cc4
[openssl-gost/engine.git] / gost_md2012.c
1 /**********************************************************************
2  *                          gost_md2012.c                             *
3  *             Copyright (c) 2013 Cryptocom LTD.                      *
4  *         This file is distributed under the same license as OpenSSL *
5  *                                                                    *
6  *          GOST R 34.11-2012 interface to OpenSSL engine.            *
7  *                                                                    *
8  * Author: Alexey Degtyarev <alexey@renatasystems.org>                *
9  *                                                                    *
10  **********************************************************************/
11
12 #include <openssl/evp.h>
13 #include "gosthash2012.h"
14
15 static int gost_digest_init512(EVP_MD_CTX *ctx);
16 static int gost_digest_init256(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 static int gost_digest_ctrl_256(EVP_MD_CTX *ctx, int type, int arg,
23                                 void *ptr);
24 static int gost_digest_ctrl_512(EVP_MD_CTX *ctx, int type, int arg,
25                                 void *ptr);
26
27 const char micalg_256[] = "gostr3411-2012-256";
28 const char micalg_512[] = "gostr3411-2012-512";
29
30 static EVP_MD *_hidden_GostR3411_2012_256_md = NULL;
31 static EVP_MD *_hidden_GostR3411_2012_512_md = NULL;
32
33 EVP_MD *digest_gost2012_256(void)
34 {
35     if (_hidden_GostR3411_2012_256_md == NULL) {
36         EVP_MD *md;
37
38         if ((md =
39              EVP_MD_meth_new(NID_id_GostR3411_2012_256, NID_undef)) == NULL
40             || !EVP_MD_meth_set_flags(md, EVP_MD_FLAG_PKEY_METHOD_SIGNATURE)
41             || !EVP_MD_meth_set_result_size(md, 32)
42             || !EVP_MD_meth_set_input_blocksize(md, 64)
43             || !EVP_MD_meth_set_app_datasize(md, sizeof(gost2012_hash_ctx))
44             || !EVP_MD_meth_set_init(md, gost_digest_init256)
45             || !EVP_MD_meth_set_update(md, gost_digest_update)
46             || !EVP_MD_meth_set_final(md, gost_digest_final)
47             || !EVP_MD_meth_set_copy(md, gost_digest_copy)
48             || !EVP_MD_meth_set_ctrl(md, gost_digest_ctrl_256)
49             || !EVP_MD_meth_set_cleanup(md, gost_digest_cleanup)) {
50             EVP_MD_meth_free(md);
51             md = NULL;
52         }
53         _hidden_GostR3411_2012_256_md = md;
54     }
55     return _hidden_GostR3411_2012_256_md;
56 }
57
58 void digest_gost2012_256_destroy(void)
59 {
60     EVP_MD_meth_free(_hidden_GostR3411_2012_256_md);
61     _hidden_GostR3411_2012_256_md = NULL;
62 }
63
64 EVP_MD *digest_gost2012_512(void)
65 {
66     if (_hidden_GostR3411_2012_512_md == NULL) {
67         EVP_MD *md;
68
69         if ((md =
70              EVP_MD_meth_new(NID_id_GostR3411_2012_512, NID_undef)) == NULL
71             || !EVP_MD_meth_set_flags(md, EVP_MD_FLAG_PKEY_METHOD_SIGNATURE)
72             || !EVP_MD_meth_set_result_size(md, 64)
73             || !EVP_MD_meth_set_input_blocksize(md, 64)
74             || !EVP_MD_meth_set_app_datasize(md, sizeof(gost2012_hash_ctx))
75             || !EVP_MD_meth_set_init(md, gost_digest_init512)
76             || !EVP_MD_meth_set_update(md, gost_digest_update)
77             || !EVP_MD_meth_set_final(md, gost_digest_final)
78             || !EVP_MD_meth_set_copy(md, gost_digest_copy)
79             || !EVP_MD_meth_set_ctrl(md, gost_digest_ctrl_512)
80             || !EVP_MD_meth_set_cleanup(md, gost_digest_cleanup)) {
81             EVP_MD_meth_free(md);
82             md = NULL;
83         }
84         _hidden_GostR3411_2012_512_md = md;
85     }
86     return _hidden_GostR3411_2012_512_md;
87 }
88
89 void digest_gost2012_512_destroy(void)
90 {
91     EVP_MD_meth_free(_hidden_GostR3411_2012_512_md);
92     _hidden_GostR3411_2012_512_md = NULL;
93 }
94
95 static int gost_digest_init512(EVP_MD_CTX *ctx)
96 {
97     init_gost2012_hash_ctx((gost2012_hash_ctx *) EVP_MD_CTX_md_data(ctx),
98                            512);
99     return 1;
100 }
101
102 static int gost_digest_init256(EVP_MD_CTX *ctx)
103 {
104     init_gost2012_hash_ctx((gost2012_hash_ctx *) EVP_MD_CTX_md_data(ctx),
105                            256);
106     return 1;
107 }
108
109 static int gost_digest_update(EVP_MD_CTX *ctx, const void *data, size_t count)
110 {
111     gost2012_hash_block((gost2012_hash_ctx *) EVP_MD_CTX_md_data(ctx), data,
112                         count);
113     return 1;
114 }
115
116 static int gost_digest_final(EVP_MD_CTX *ctx, unsigned char *md)
117 {
118     gost2012_finish_hash((gost2012_hash_ctx *) EVP_MD_CTX_md_data(ctx), md);
119     return 1;
120 }
121
122 static int gost_digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from)
123 {
124     if (EVP_MD_CTX_md_data(to) && EVP_MD_CTX_md_data(from))
125         memcpy(EVP_MD_CTX_md_data(to), EVP_MD_CTX_md_data(from),
126                sizeof(gost2012_hash_ctx));
127
128     return 1;
129 }
130
131 static int gost_digest_cleanup(EVP_MD_CTX *ctx)
132 {
133     if (EVP_MD_CTX_md_data(ctx))
134         memset(EVP_MD_CTX_md_data(ctx), 0x00, sizeof(gost2012_hash_ctx));
135
136     return 1;
137 }
138
139 static int gost_digest_ctrl_256(EVP_MD_CTX *ctx, int type, int arg, void *ptr)
140 {
141     switch (type) {
142     case EVP_MD_CTRL_MICALG:
143         {
144             *((char **)ptr) = OPENSSL_malloc(strlen(micalg_256) + 1);
145             if (*((char **)ptr) != NULL) {
146                 strcpy(*((char **)ptr), micalg_256);
147                 return 1;
148             }
149             return 0;
150         }
151     default:
152         return 0;
153     }
154 }
155
156 static int gost_digest_ctrl_512(EVP_MD_CTX *ctx, int type, int arg, void *ptr)
157 {
158     switch (type) {
159     case EVP_MD_CTRL_MICALG:
160         {
161             *((char **)ptr) = OPENSSL_malloc(strlen(micalg_512) + 1);
162             if (*((char **)ptr) != NULL) {
163                 strcpy(*((char **)ptr), micalg_512);
164                 return 1;
165             }
166         }
167     default:
168         return 0;
169     }
170 }