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_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)) {
53 _hidden_GostR3411_2012_256_md = md;
55 return _hidden_GostR3411_2012_256_md;
58 void digest_gost2012_256_destroy(void)
60 EVP_MD_meth_free(_hidden_GostR3411_2012_256_md);
61 _hidden_GostR3411_2012_256_md = NULL;
64 EVP_MD *digest_gost2012_512(void)
66 if (_hidden_GostR3411_2012_512_md == NULL) {
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)) {
84 _hidden_GostR3411_2012_512_md = md;
86 return _hidden_GostR3411_2012_512_md;
89 void digest_gost2012_512_destroy(void)
91 EVP_MD_meth_free(_hidden_GostR3411_2012_512_md);
92 _hidden_GostR3411_2012_512_md = NULL;
95 static int gost_digest_init512(EVP_MD_CTX *ctx)
97 init_gost2012_hash_ctx((gost2012_hash_ctx *) EVP_MD_CTX_md_data(ctx),
102 static int gost_digest_init256(EVP_MD_CTX *ctx)
104 init_gost2012_hash_ctx((gost2012_hash_ctx *) EVP_MD_CTX_md_data(ctx),
109 static int gost_digest_update(EVP_MD_CTX *ctx, const void *data, size_t count)
111 gost2012_hash_block((gost2012_hash_ctx *) EVP_MD_CTX_md_data(ctx), data,
116 static int gost_digest_final(EVP_MD_CTX *ctx, unsigned char *md)
118 gost2012_finish_hash((gost2012_hash_ctx *) EVP_MD_CTX_md_data(ctx), md);
122 static int gost_digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from)
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));
131 static int gost_digest_cleanup(EVP_MD_CTX *ctx)
133 if (EVP_MD_CTX_md_data(ctx))
134 memset(EVP_MD_CTX_md_data(ctx), 0x00, sizeof(gost2012_hash_ctx));
139 static int gost_digest_ctrl_256(EVP_MD_CTX *ctx, int type, int arg, void *ptr)
142 case EVP_MD_CTRL_MICALG:
144 *((char **)ptr) = OPENSSL_malloc(strlen(micalg_256) + 1);
145 if (*((char **)ptr) != NULL) {
146 strcpy(*((char **)ptr), micalg_256);
156 static int gost_digest_ctrl_512(EVP_MD_CTX *ctx, int type, int arg, void *ptr)
159 case EVP_MD_CTRL_MICALG:
161 *((char **)ptr) = OPENSSL_malloc(strlen(micalg_512) + 1);
162 if (*((char **)ptr) != NULL) {
163 strcpy(*((char **)ptr), micalg_512);