ebf0b625b5b316aba7b0f38f4ebe833d10f04f83
[openssl.git] / engines / ccgost / gost_eng.c
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 static int gost_engine_init(ENGINE *e)
55         { 
56         return 1;
57         }
58
59 static int gost_engine_finish(ENGINE *e)
60         { 
61         return 1;
62         }
63
64 static int gost_engine_destroy(ENGINE *e)
65         { 
66         gost_param_free();
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;
74         return 1;
75         }
76
77 static int bind_gost (ENGINE *e,const char *id) 
78         {
79         int ret = 0;
80         if (id && strcmp(id, engine_gost_id)) return 0;
81
82         if (!ENGINE_set_id(e, engine_gost_id)) 
83                 {
84                 printf("ENGINE_set_id failed\n"); 
85                 goto end;
86                 }       
87         if (!ENGINE_set_name(e, engine_gost_name)) 
88                 {
89                 printf("ENGINE_set_name failed\n");
90                 goto end;
91                 }       
92         if (!ENGINE_set_digests(e, gost_digests)) 
93                 {
94                 printf("ENGINE_set_digests failed\n");
95                 goto end;
96                 }       
97         if (! ENGINE_set_ciphers(e, gost_ciphers)) 
98                 {
99                 printf("ENGINE_set_ciphers failed\n");
100                 goto end;
101                 }       
102         if (! ENGINE_set_pkey_meths(e, gost_pkey_meths)) 
103                 {
104                 printf("ENGINE_set_pkey_meths failed\n");
105                 goto end;
106                 }       
107         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         if (!ENGINE_set_cmd_defns(e,gost_cmds)) 
114                 {
115                 fprintf(stderr,"ENGINE_set_cmd_defns failed\n");
116                 goto end;
117                 }       
118         if (!ENGINE_set_ctrl_function(e,gost_control_func)) 
119                 {
120                 fprintf(stderr,"ENGINE_set_ctrl_func failed\n");
121                 goto end;
122                 }       
123         if ( ! ENGINE_set_destroy_function(e, gost_engine_destroy)
124                 || ! ENGINE_set_init_function(e,gost_engine_init)
125                 || ! ENGINE_set_finish_function(e,gost_engine_finish))
126                 {
127                 goto end;
128                 }
129
130         if (!register_ameth_gost(NID_id_GostR3410_94, &ameth_GostR3410_94, "GOST94", "GOST R 34.10-94")) goto end;
131         if (!register_ameth_gost(NID_id_GostR3410_2001, &ameth_GostR3410_2001, "GOST2001", "GOST R 34.10-2001")) goto end;
132         if (!register_ameth_gost(NID_id_Gost28147_89_MAC, &ameth_Gost28147_MAC,
133                 "GOST-MAC", "GOST 28147-89 MAC")) goto end;
134
135         if (!register_pmeth_gost(NID_id_GostR3410_94, &pmeth_GostR3410_94, 0)) goto end;
136         if (!register_pmeth_gost(NID_id_GostR3410_2001, &pmeth_GostR3410_2001, 0)) goto end;
137         if (!register_pmeth_gost(NID_id_Gost28147_89_MAC, &pmeth_Gost28147_MAC, 0))
138                 goto end;
139         if ( ! ENGINE_register_ciphers(e)
140                 || ! ENGINE_register_digests(e)
141                 || ! ENGINE_register_pkey_meths(e)
142                 /* These two actually should go in LIST_ADD command */
143                 || ! EVP_add_cipher(&cipher_gost)
144                 || ! EVP_add_cipher(&cipher_gost_cpacnt)
145                 || ! EVP_add_digest(&digest_gost)
146                 || ! EVP_add_digest(&imit_gost_cpa)
147                 )
148                 {
149                 goto end;
150                 }
151
152         ERR_load_GOST_strings();
153         ret = 1;
154         end:
155         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 static int gost_digests(ENGINE *e, const EVP_MD **digest,
164         const int **nids, int nid)
165         { 
166         int ok =1 ;
167         if (!digest) 
168                 {
169                 *nids = gost_digest_nids;
170                 return 2; 
171                 }
172         /*printf("Digest no %d requested\n",nid);*/
173         if(nid == NID_id_GostR3411_94) 
174                 {
175                 *digest = &digest_gost;
176                 }
177         else if (nid == NID_id_Gost28147_89_MAC) 
178                 {
179                 *digest = &imit_gost_cpa;
180                 }
181         else
182                 {
183                 ok =0;
184                 *digest = NULL;
185                 }
186         return ok;
187         }       
188         
189 static int gost_ciphers (ENGINE *e,const EVP_CIPHER **cipher,
190         const int **nids, int nid) 
191         {
192         int ok = 1;
193         if (!cipher) 
194                 {
195                 *nids = gost_cipher_nids;
196                 return 2; /* two ciphers are supported */
197                 }
198
199         if(nid == NID_id_Gost28147_89) 
200                 {
201                 *cipher = &cipher_gost;
202                 }
203         else if  (nid == NID_gost89_cnt) 
204                 {
205                 *cipher = &cipher_gost_cpacnt;
206                 }
207         else    
208                 {
209                 ok = 0;
210                 *cipher = NULL;
211                 }
212         return ok;
213         }       
214
215 static int gost_pkey_meths (ENGINE *e, EVP_PKEY_METHOD **pmeth,
216         const int **nids, int nid)
217         {
218         if (!pmeth) 
219                 {
220                 *nids = gost_pkey_meth_nids;
221                 return 3;
222                 }
223
224         switch (nid) 
225                 {
226                 case NID_id_GostR3410_94: *pmeth = pmeth_GostR3410_94; return 1;
227                 case NID_id_GostR3410_2001: *pmeth = pmeth_GostR3410_2001; return 1;
228                 case NID_id_Gost28147_89_MAC: *pmeth = pmeth_Gost28147_MAC; return 1;
229                 default:;
230                 }
231         
232         *pmeth = NULL;
233         return 0;
234         }
235
236 static int gost_pkey_asn1_meths (ENGINE *e, EVP_PKEY_ASN1_METHOD **ameth,
237         const int **nids, int nid)
238         {
239         if (!ameth) 
240                 {
241                 *nids = gost_pkey_meth_nids;
242                 return 3;
243                 }
244         switch (nid) 
245                 {
246                 case NID_id_GostR3410_94: *ameth = ameth_GostR3410_94; return 1;
247                 case NID_id_GostR3410_2001: *ameth = ameth_GostR3410_2001; return 1;
248                 case NID_id_Gost28147_89_MAC: *ameth = ameth_Gost28147_MAC; return 1;
249         
250                 default:;
251                 }
252         
253         *ameth = NULL;
254         return 0;
255         }
256
257 #ifdef OPENSSL_NO_DYNAMIC_ENGINE
258 static ENGINE *engine_gost(void)
259         {       
260         ENGINE *ret = ENGINE_new();
261         if (!ret)
262                 return NULL;
263         if (!bind_gost(ret,engine_gost_id)) 
264                 {
265                 ENGINE_free(ret);
266                 return NULL;
267                 }
268         return ret;
269         }
270         
271 void ENGINE_load_gost(void)
272         {
273         ENGINE *toadd;
274         if (pmeth_GostR3410_94)
275                 return;
276         toadd = engine_gost();
277         if (!toadd) return;
278         ENGINE_add(toadd);
279         ENGINE_free(toadd);
280         ERR_clear_error();
281         }
282 #endif  
283