1 /**********************************************************************
3 * Copyright (c) 2013 Cryptocom LTD. *
4 * This file is distributed under the same license as OpenSSL *
6 * GOST R 34.11-2012 interface to OpenSSL engine. *
8 * Author: Alexey Degtyarev <alexey@renatasystems.org> *
10 **********************************************************************/
12 #include <openssl/evp.h>
13 #include "gosthash2012.h"
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,
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,
24 static int gost_digest_ctrl_512(EVP_MD_CTX *ctx, int type, int arg,
27 const char micalg_256[] = "gostr3411-2012-256";
28 const char micalg_512[] = "gostr3411-2012-512";
30 static EVP_MD *_hidden_GostR3411_2012_256_md = NULL;
31 static EVP_MD *_hidden_GostR3411_2012_512_md = NULL;
33 EVP_MD *digest_gost2012_256(void)
35 if (_hidden_GostR3411_2012_256_md == NULL) {
39 EVP_MD_meth_new(NID_id_GostR3411_2012_256, NID_undef)) == NULL
40 || !EVP_MD_meth_set_result_size(md, 32)
41 || !EVP_MD_meth_set_input_blocksize(md, 64)
42 || !EVP_MD_meth_set_app_datasize(md, sizeof(gost2012_hash_ctx))
43 || !EVP_MD_meth_set_init(md, gost_digest_init256)
44 || !EVP_MD_meth_set_update(md, gost_digest_update)
45 || !EVP_MD_meth_set_final(md, gost_digest_final)
46 || !EVP_MD_meth_set_copy(md, gost_digest_copy)
47 || !EVP_MD_meth_set_ctrl(md, gost_digest_ctrl_256)
48 || !EVP_MD_meth_set_cleanup(md, gost_digest_cleanup)) {
52 _hidden_GostR3411_2012_256_md = md;
54 return _hidden_GostR3411_2012_256_md;
57 void digest_gost2012_256_destroy(void)
59 EVP_MD_meth_free(_hidden_GostR3411_2012_256_md);
60 _hidden_GostR3411_2012_256_md = NULL;
63 EVP_MD *digest_gost2012_512(void)
65 if (_hidden_GostR3411_2012_512_md == NULL) {
69 EVP_MD_meth_new(NID_id_GostR3411_2012_512, NID_undef)) == NULL
70 || !EVP_MD_meth_set_result_size(md, 64)
71 || !EVP_MD_meth_set_input_blocksize(md, 64)
72 || !EVP_MD_meth_set_app_datasize(md, sizeof(gost2012_hash_ctx))
73 || !EVP_MD_meth_set_init(md, gost_digest_init512)
74 || !EVP_MD_meth_set_update(md, gost_digest_update)
75 || !EVP_MD_meth_set_final(md, gost_digest_final)
76 || !EVP_MD_meth_set_copy(md, gost_digest_copy)
77 || !EVP_MD_meth_set_ctrl(md, gost_digest_ctrl_512)
78 || !EVP_MD_meth_set_cleanup(md, gost_digest_cleanup)) {
82 _hidden_GostR3411_2012_512_md = md;
84 return _hidden_GostR3411_2012_512_md;
87 void digest_gost2012_512_destroy(void)
89 EVP_MD_meth_free(_hidden_GostR3411_2012_512_md);
90 _hidden_GostR3411_2012_512_md = NULL;
93 static int gost_digest_init512(EVP_MD_CTX *ctx)
95 init_gost2012_hash_ctx((gost2012_hash_ctx *) EVP_MD_CTX_md_data(ctx),
100 static int gost_digest_init256(EVP_MD_CTX *ctx)
102 init_gost2012_hash_ctx((gost2012_hash_ctx *) EVP_MD_CTX_md_data(ctx),
107 static int gost_digest_update(EVP_MD_CTX *ctx, const void *data, size_t count)
109 gost2012_hash_block((gost2012_hash_ctx *) EVP_MD_CTX_md_data(ctx), data,
114 static int gost_digest_final(EVP_MD_CTX *ctx, unsigned char *md)
116 gost2012_finish_hash((gost2012_hash_ctx *) EVP_MD_CTX_md_data(ctx), md);
120 static int gost_digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from)
122 if (EVP_MD_CTX_md_data(to) && EVP_MD_CTX_md_data(from))
123 memcpy(EVP_MD_CTX_md_data(to), EVP_MD_CTX_md_data(from),
124 sizeof(gost2012_hash_ctx));
129 static int gost_digest_cleanup(EVP_MD_CTX *ctx)
131 if (EVP_MD_CTX_md_data(ctx))
132 memset(EVP_MD_CTX_md_data(ctx), 0x00, sizeof(gost2012_hash_ctx));
137 static int gost_digest_ctrl_256(EVP_MD_CTX *ctx, int type, int arg, void *ptr)
140 case EVP_MD_CTRL_MICALG:
142 *((char **)ptr) = OPENSSL_malloc(strlen(micalg_256) + 1);
143 if (*((char **)ptr) != NULL) {
144 strcpy(*((char **)ptr), micalg_256);
154 static int gost_digest_ctrl_512(EVP_MD_CTX *ctx, int type, int arg, void *ptr)
157 case EVP_MD_CTRL_MICALG:
159 *((char **)ptr) = OPENSSL_malloc(strlen(micalg_512) + 1);
160 if (*((char **)ptr) != NULL) {
161 strcpy(*((char **)ptr), micalg_512);