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) {
38 if ((md = EVP_MD_meth_new(NID_id_GostR3411_2012_256, NID_undef)) == NULL
39 || !EVP_MD_meth_set_result_size(md, 32)
40 || !EVP_MD_meth_set_input_blocksize(md, 64)
41 || !EVP_MD_meth_set_app_datasize(md, sizeof(gost2012_hash_ctx))
42 || !EVP_MD_meth_set_init(md, gost_digest_init256)
43 || !EVP_MD_meth_set_update(md, gost_digest_update)
44 || !EVP_MD_meth_set_final(md, gost_digest_final)
45 || !EVP_MD_meth_set_copy(md, gost_digest_copy)
46 || !EVP_MD_meth_set_ctrl(md, gost_digest_ctrl_256)
47 || !EVP_MD_meth_set_cleanup(md, gost_digest_cleanup)) {
51 _hidden_GostR3411_2012_256_md = md;
53 return _hidden_GostR3411_2012_256_md;
56 void digest_gost2012_256_destroy(void)
58 EVP_MD_meth_free(_hidden_GostR3411_2012_256_md);
59 _hidden_GostR3411_2012_256_md = NULL;
62 EVP_MD *digest_gost2012_512(void)
64 if (_hidden_GostR3411_2012_512_md == NULL) {
67 if ((md = EVP_MD_meth_new(NID_id_GostR3411_2012_512, NID_undef)) == NULL
68 || !EVP_MD_meth_set_result_size(md, 64)
69 || !EVP_MD_meth_set_input_blocksize(md, 64)
70 || !EVP_MD_meth_set_app_datasize(md, sizeof(gost2012_hash_ctx))
71 || !EVP_MD_meth_set_init(md, gost_digest_init512)
72 || !EVP_MD_meth_set_update(md, gost_digest_update)
73 || !EVP_MD_meth_set_final(md, gost_digest_final)
74 || !EVP_MD_meth_set_copy(md, gost_digest_copy)
75 || !EVP_MD_meth_set_ctrl(md, gost_digest_ctrl_512)
76 || !EVP_MD_meth_set_cleanup(md, gost_digest_cleanup)) {
80 _hidden_GostR3411_2012_512_md = md;
82 return _hidden_GostR3411_2012_512_md;
85 void digest_gost2012_512_destroy(void)
87 EVP_MD_meth_free(_hidden_GostR3411_2012_512_md);
88 _hidden_GostR3411_2012_512_md = NULL;
91 static int gost_digest_init512(EVP_MD_CTX *ctx)
93 init_gost2012_hash_ctx((gost2012_hash_ctx *) EVP_MD_CTX_md_data(ctx), 512);
97 static int gost_digest_init256(EVP_MD_CTX *ctx)
99 init_gost2012_hash_ctx((gost2012_hash_ctx *) EVP_MD_CTX_md_data(ctx), 256);
103 static int gost_digest_update(EVP_MD_CTX *ctx, const void *data, size_t count)
105 gost2012_hash_block((gost2012_hash_ctx *) EVP_MD_CTX_md_data(ctx), data, count);
109 static int gost_digest_final(EVP_MD_CTX *ctx, unsigned char *md)
111 gost2012_finish_hash((gost2012_hash_ctx *) EVP_MD_CTX_md_data(ctx), md);
115 static int gost_digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from)
117 if (EVP_MD_CTX_md_data(to) && EVP_MD_CTX_md_data(from))
118 memcpy(EVP_MD_CTX_md_data(to), EVP_MD_CTX_md_data(from), sizeof(gost2012_hash_ctx));
123 static int gost_digest_cleanup(EVP_MD_CTX *ctx)
125 if (EVP_MD_CTX_md_data(ctx))
126 memset(EVP_MD_CTX_md_data(ctx), 0x00, sizeof(gost2012_hash_ctx));
131 static int gost_digest_ctrl_256(EVP_MD_CTX *ctx, int type, int arg, void *ptr)
134 case EVP_MD_CTRL_MICALG:
136 *((char **)ptr) = OPENSSL_malloc(strlen(micalg_256) + 1);
137 if (*((char **)ptr) != NULL) {
138 strcpy(*((char **)ptr), micalg_256);
148 static int gost_digest_ctrl_512(EVP_MD_CTX *ctx, int type, int arg, void *ptr)
151 case EVP_MD_CTRL_MICALG:
153 *((char **)ptr) = OPENSSL_malloc(strlen(micalg_512) + 1);
154 if (*((char **)ptr) != NULL) {
155 strcpy(*((char **)ptr), micalg_512);