Branch data Line data Source code
1 : : /**********************************************************************
2 : : * gost_eng.c *
3 : : * Copyright (c) 2005-2006 Cryptocom LTD *
4 : : * This file is distributed under the same license as OpenSSL *
5 : : * *
6 : : * Main file of GOST engine *
7 : : * for OpenSSL *
8 : : * Requires OpenSSL 0.9.9 for compilation *
9 : : **********************************************************************/
10 : : #include <string.h>
11 : : #include <openssl/crypto.h>
12 : : #include <openssl/err.h>
13 : : #include <openssl/evp.h>
14 : : #include <openssl/engine.h>
15 : : #include <openssl/obj_mac.h>
16 : : #include "e_gost_err.h"
17 : : #include "gost_lcl.h"
18 : : static const char *engine_gost_id = "gost";
19 : : static const char *engine_gost_name = "Reference implementation of GOST engine";
20 : :
21 : : /* Symmetric cipher and digest function registrar */
22 : :
23 : : static int gost_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
24 : : const int **nids, int nid);
25 : :
26 : : static int gost_digests(ENGINE *e, const EVP_MD **digest,
27 : : const int **nids, int ind);
28 : :
29 : : static int gost_pkey_meths (ENGINE *e, EVP_PKEY_METHOD **pmeth,
30 : : const int **nids, int nid);
31 : :
32 : : static int gost_pkey_asn1_meths (ENGINE *e, EVP_PKEY_ASN1_METHOD **ameth,
33 : : const int **nids, int nid);
34 : :
35 : : static int gost_cipher_nids[] =
36 : : {NID_id_Gost28147_89, NID_gost89_cnt,0};
37 : :
38 : : static int gost_digest_nids[] =
39 : : {NID_id_GostR3411_94,NID_id_Gost28147_89_MAC, 0};
40 : :
41 : : static int gost_pkey_meth_nids[] =
42 : : {NID_id_GostR3410_94,
43 : : NID_id_GostR3410_2001, NID_id_Gost28147_89_MAC, 0};
44 : :
45 : : static EVP_PKEY_METHOD *pmeth_GostR3410_94 = NULL,
46 : : *pmeth_GostR3410_2001 = NULL,
47 : : *pmeth_Gost28147_MAC = NULL;
48 : :
49 : : static EVP_PKEY_ASN1_METHOD *ameth_GostR3410_94 = NULL,
50 : : *ameth_GostR3410_2001 = NULL,
51 : : *ameth_Gost28147_MAC = NULL;
52 : :
53 : :
54 : 1 : static int gost_engine_init(ENGINE *e)
55 : : {
56 : 1 : return 1;
57 : : }
58 : :
59 : 0 : static int gost_engine_finish(ENGINE *e)
60 : : {
61 : 0 : return 1;
62 : : }
63 : :
64 : 727 : static int gost_engine_destroy(ENGINE *e)
65 : : {
66 : 727 : gost_param_free();
67 : :
68 : 727 : pmeth_GostR3410_94 = NULL;
69 : 727 : pmeth_GostR3410_2001 = NULL;
70 : 727 : pmeth_Gost28147_MAC = NULL;
71 : 727 : ameth_GostR3410_94 = NULL;
72 : 727 : ameth_GostR3410_2001 = NULL;
73 : 727 : ameth_Gost28147_MAC = NULL;
74 : 727 : return 1;
75 : : }
76 : :
77 : 728 : static int bind_gost (ENGINE *e,const char *id)
78 : : {
79 : 728 : int ret = 0;
80 [ + - ][ + - ]: 728 : if (id && strcmp(id, engine_gost_id)) return 0;
81 : :
82 [ - + ]: 728 : if (!ENGINE_set_id(e, engine_gost_id))
83 : : {
84 : : printf("ENGINE_set_id failed\n");
85 : : goto end;
86 : : }
87 [ - + ]: 728 : if (!ENGINE_set_name(e, engine_gost_name))
88 : : {
89 : : printf("ENGINE_set_name failed\n");
90 : : goto end;
91 : : }
92 [ - + ]: 728 : if (!ENGINE_set_digests(e, gost_digests))
93 : : {
94 : : printf("ENGINE_set_digests failed\n");
95 : : goto end;
96 : : }
97 [ - + ]: 728 : if (! ENGINE_set_ciphers(e, gost_ciphers))
98 : : {
99 : : printf("ENGINE_set_ciphers failed\n");
100 : : goto end;
101 : : }
102 [ - + ]: 728 : if (! ENGINE_set_pkey_meths(e, gost_pkey_meths))
103 : : {
104 : : printf("ENGINE_set_pkey_meths failed\n");
105 : : goto end;
106 : : }
107 [ - + ]: 728 : if (! ENGINE_set_pkey_asn1_meths(e, gost_pkey_asn1_meths))
108 : : {
109 : : printf("ENGINE_set_pkey_asn1_meths failed\n");
110 : : goto end;
111 : : }
112 : : /* Control function and commands */
113 [ - + ]: 728 : if (!ENGINE_set_cmd_defns(e,gost_cmds))
114 : : {
115 : 0 : fprintf(stderr,"ENGINE_set_cmd_defns failed\n");
116 : : goto end;
117 : : }
118 [ - + ]: 728 : if (!ENGINE_set_ctrl_function(e,gost_control_func))
119 : : {
120 : 0 : fprintf(stderr,"ENGINE_set_ctrl_func failed\n");
121 : : goto end;
122 : : }
123 [ + - ]: 728 : if ( ! ENGINE_set_destroy_function(e, gost_engine_destroy)
124 [ + - ]: 728 : || ! ENGINE_set_init_function(e,gost_engine_init)
125 [ + - ]: 728 : || ! ENGINE_set_finish_function(e,gost_engine_finish))
126 : : {
127 : : goto end;
128 : : }
129 : :
130 [ + - ]: 728 : if (!register_ameth_gost(NID_id_GostR3410_94, &ameth_GostR3410_94, "GOST94", "GOST R 34.10-94")) goto end;
131 [ + - ]: 728 : if (!register_ameth_gost(NID_id_GostR3410_2001, &ameth_GostR3410_2001, "GOST2001", "GOST R 34.10-2001")) goto end;
132 [ + - ]: 728 : if (!register_ameth_gost(NID_id_Gost28147_89_MAC, &ameth_Gost28147_MAC,
133 : : "GOST-MAC", "GOST 28147-89 MAC")) goto end;
134 : :
135 [ + - ]: 728 : if (!register_pmeth_gost(NID_id_GostR3410_94, &pmeth_GostR3410_94, 0)) goto end;
136 [ + - ]: 728 : if (!register_pmeth_gost(NID_id_GostR3410_2001, &pmeth_GostR3410_2001, 0)) goto end;
137 [ + - ]: 728 : if (!register_pmeth_gost(NID_id_Gost28147_89_MAC, &pmeth_Gost28147_MAC, 0))
138 : : goto end;
139 [ + - ]: 728 : if ( ! ENGINE_register_ciphers(e)
140 [ + - ]: 728 : || ! ENGINE_register_digests(e)
141 [ + - ]: 728 : || ! ENGINE_register_pkey_meths(e)
142 : : /* These two actually should go in LIST_ADD command */
143 [ + - ]: 728 : || ! EVP_add_cipher(&cipher_gost)
144 [ + - ]: 728 : || ! EVP_add_cipher(&cipher_gost_cpacnt)
145 [ + - ]: 728 : || ! EVP_add_digest(&digest_gost)
146 [ + - ]: 728 : || ! EVP_add_digest(&imit_gost_cpa)
147 : : )
148 : : {
149 : : goto end;
150 : : }
151 : :
152 : 728 : ERR_load_GOST_strings();
153 : 728 : ret = 1;
154 : : end:
155 : 728 : return ret;
156 : : }
157 : :
158 : : #ifndef OPENSSL_NO_DYNAMIC_ENGINE
159 : : IMPLEMENT_DYNAMIC_BIND_FN(bind_gost)
160 : : IMPLEMENT_DYNAMIC_CHECK_FN()
161 : : #endif /* ndef OPENSSL_NO_DYNAMIC_ENGINE */
162 : :
163 : 1489 : static int gost_digests(ENGINE *e, const EVP_MD **digest,
164 : : const int **nids, int nid)
165 : : {
166 : 1489 : int ok =1 ;
167 [ + + ]: 1489 : if (!digest)
168 : : {
169 : 1459 : *nids = gost_digest_nids;
170 : 1459 : return 2;
171 : : }
172 : : /*printf("Digest no %d requested\n",nid);*/
173 [ + + ]: 30 : if(nid == NID_id_GostR3411_94)
174 : : {
175 : 23 : *digest = &digest_gost;
176 : : }
177 [ + - ]: 7 : else if (nid == NID_id_Gost28147_89_MAC)
178 : : {
179 : 7 : *digest = &imit_gost_cpa;
180 : : }
181 : : else
182 : : {
183 : 0 : ok =0;
184 : 0 : *digest = NULL;
185 : : }
186 : 30 : return ok;
187 : : }
188 : :
189 : 1466 : static int gost_ciphers (ENGINE *e,const EVP_CIPHER **cipher,
190 : : const int **nids, int nid)
191 : : {
192 : 1466 : int ok = 1;
193 [ + + ]: 1466 : if (!cipher)
194 : : {
195 : 1458 : *nids = gost_cipher_nids;
196 : 1458 : return 2; /* two ciphers are supported */
197 : : }
198 : :
199 [ + + ]: 8 : if(nid == NID_id_Gost28147_89)
200 : : {
201 : 5 : *cipher = &cipher_gost;
202 : : }
203 [ + - ]: 3 : else if (nid == NID_gost89_cnt)
204 : : {
205 : 3 : *cipher = &cipher_gost_cpacnt;
206 : : }
207 : : else
208 : : {
209 : 0 : ok = 0;
210 : 0 : *cipher = NULL;
211 : : }
212 : 8 : return ok;
213 : : }
214 : :
215 : 4379 : static int gost_pkey_meths (ENGINE *e, EVP_PKEY_METHOD **pmeth,
216 : : const int **nids, int nid)
217 : : {
218 [ + + ]: 4379 : if (!pmeth)
219 : : {
220 : 2184 : *nids = gost_pkey_meth_nids;
221 : 2184 : return 3;
222 : : }
223 : :
224 [ + + + - ]: 2195 : switch (nid)
225 : : {
226 : 727 : case NID_id_GostR3410_94: *pmeth = pmeth_GostR3410_94; return 1;
227 : 727 : case NID_id_GostR3410_2001: *pmeth = pmeth_GostR3410_2001; return 1;
228 : 741 : case NID_id_Gost28147_89_MAC: *pmeth = pmeth_Gost28147_MAC; return 1;
229 : : default:;
230 : : }
231 : :
232 : 0 : *pmeth = NULL;
233 : 0 : return 0;
234 : : }
235 : :
236 : 2916 : static int gost_pkey_asn1_meths (ENGINE *e, EVP_PKEY_ASN1_METHOD **ameth,
237 : : const int **nids, int nid)
238 : : {
239 [ + + ]: 2916 : if (!ameth)
240 : : {
241 : 728 : *nids = gost_pkey_meth_nids;
242 : 728 : return 3;
243 : : }
244 [ + + + - ]: 2188 : switch (nid)
245 : : {
246 : 727 : case NID_id_GostR3410_94: *ameth = ameth_GostR3410_94; return 1;
247 : 727 : case NID_id_GostR3410_2001: *ameth = ameth_GostR3410_2001; return 1;
248 : 734 : case NID_id_Gost28147_89_MAC: *ameth = ameth_Gost28147_MAC; return 1;
249 : :
250 : : default:;
251 : : }
252 : :
253 : 0 : *ameth = NULL;
254 : 0 : return 0;
255 : : }
256 : :
257 : : #ifdef OPENSSL_NO_DYNAMIC_ENGINE
258 : 728 : static ENGINE *engine_gost(void)
259 : : {
260 : 728 : ENGINE *ret = ENGINE_new();
261 [ + - ]: 728 : if (!ret)
262 : : return NULL;
263 [ - + ]: 728 : if (!bind_gost(ret,engine_gost_id))
264 : : {
265 : 0 : ENGINE_free(ret);
266 : 0 : return NULL;
267 : : }
268 : : return ret;
269 : : }
270 : :
271 : 728 : void ENGINE_load_gost(void)
272 : : {
273 : : ENGINE *toadd;
274 [ + - ]: 728 : if (pmeth_GostR3410_94)
275 : : return;
276 : 728 : toadd = engine_gost();
277 [ + - ]: 728 : if (!toadd) return;
278 : 728 : ENGINE_add(toadd);
279 : 728 : ENGINE_free(toadd);
280 : 728 : ERR_clear_error();
281 : : }
282 : : #endif
283 : :
|