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