]> www.wagner.pp.ru Git - openssl-gost/engine.git/blob - gost_eng.c
Delete .travis.yml
[openssl-gost/engine.git] / gost_eng.c
1 /**********************************************************************
2  *                          gost_eng.c                                *
3  *              Main file of GOST engine                              *
4  *                                                                    *
5  *             Copyright (c) 2005-2006 Cryptocom LTD                  *
6  *             Copyright (c) 2020 Chikunov Vitaly <vt@altlinux.org>   *
7  *                                                                    *
8  *       This file is distributed under the same license as OpenSSL   *
9  *                                                                    *
10  **********************************************************************/
11 #include <string.h>
12 #include <openssl/crypto.h>
13 #include <openssl/err.h>
14 #include <openssl/evp.h>
15 #include <openssl/engine.h>
16 #include <openssl/obj_mac.h>
17 #include "e_gost_err.h"
18 #include "gost_lcl.h"
19
20 #include "gost_grasshopper_cipher.h"
21
22 static const char* engine_gost_id = "gost";
23
24 static const char* engine_gost_name =
25         "Reference implementation of GOST engine";
26
27 /* Symmetric cipher and digest function registrar */
28
29 static int gost_ciphers(ENGINE* e, const EVP_CIPHER** cipher,
30                         const int** nids, int nid);
31
32 static int gost_digests(ENGINE* e, const EVP_MD** digest,
33                         const int** nids, int nid);
34
35 static int gost_pkey_meths(ENGINE* e, EVP_PKEY_METHOD** pmeth,
36                            const int** nids, int nid);
37
38 static int gost_pkey_asn1_meths(ENGINE* e, EVP_PKEY_ASN1_METHOD** ameth,
39                                 const int** nids, int nid);
40
41 static EVP_PKEY_METHOD* pmeth_GostR3410_2001 = NULL,
42         * pmeth_GostR3410_2001DH = NULL,
43         * pmeth_GostR3410_2012_256 = NULL,
44         * pmeth_GostR3410_2012_512 = NULL,
45         * pmeth_Gost28147_MAC = NULL, * pmeth_Gost28147_MAC_12 = NULL,
46         * pmeth_magma_mac = NULL,  * pmeth_grasshopper_mac = NULL,
47         * pmeth_magma_mac_acpkm = NULL,  * pmeth_grasshopper_mac_acpkm = NULL;
48
49 static EVP_PKEY_ASN1_METHOD* ameth_GostR3410_2001 = NULL,
50         * ameth_GostR3410_2001DH = NULL,
51         * ameth_GostR3410_2012_256 = NULL,
52         * ameth_GostR3410_2012_512 = NULL,
53         * ameth_Gost28147_MAC = NULL, * ameth_Gost28147_MAC_12 = NULL,
54         * ameth_magma_mac = NULL,  * ameth_grasshopper_mac = NULL,
55         * ameth_magma_mac_acpkm = NULL,  * ameth_grasshopper_mac_acpkm = NULL;
56
57 GOST_digest *gost_digest_array[] = {
58     &GostR3411_94_digest,
59     &Gost28147_89_MAC_digest,
60     &GostR3411_2012_256_digest,
61     &GostR3411_2012_512_digest,
62     &Gost28147_89_mac_12_digest,
63     &magma_mac_digest,
64     &grasshopper_mac_digest,
65     &kuznyechik_ctracpkm_omac_digest,
66 };
67
68 GOST_cipher *gost_cipher_array[] = {
69     &Gost28147_89_cipher,
70     &Gost28147_89_cnt_cipher,
71     &Gost28147_89_cnt_12_cipher,
72     &Gost28147_89_cbc_cipher,
73     &grasshopper_ecb_cipher,
74     &grasshopper_cbc_cipher,
75     &grasshopper_cfb_cipher,
76     &grasshopper_ofb_cipher,
77     &grasshopper_ctr_cipher,
78     &grasshopper_mgm_cipher,
79     &magma_cbc_cipher,
80     &magma_ctr_cipher,
81     &magma_ctr_acpkm_cipher,
82     &magma_ctr_acpkm_omac_cipher,
83     &magma_mgm_cipher,
84     &grasshopper_ctr_acpkm_cipher,
85     &grasshopper_ctr_acpkm_omac_cipher,
86     &magma_kexp15_cipher,
87     &kuznyechik_kexp15_cipher,
88 };
89
90 static struct gost_meth_minfo {
91     int nid;
92     EVP_PKEY_METHOD **pmeth;
93     EVP_PKEY_ASN1_METHOD **ameth;
94     const char *pemstr;
95     const char *info;
96 } gost_meth_array[] = {
97     {
98         NID_id_GostR3410_2001,
99         &pmeth_GostR3410_2001,
100         &ameth_GostR3410_2001,
101         "GOST2001",
102         "GOST R 34.10-2001",
103     },
104     {
105         NID_id_GostR3410_2001DH,
106         &pmeth_GostR3410_2001DH,
107         &ameth_GostR3410_2001DH,
108         "GOST2001 DH",
109         "GOST R 34.10-2001 DH",
110     },
111     {
112         NID_id_Gost28147_89_MAC,
113         &pmeth_Gost28147_MAC,
114         &ameth_Gost28147_MAC,
115         "GOST-MAC",
116         "GOST 28147-89 MAC",
117     },
118     {
119         NID_id_GostR3410_2012_256,
120         &pmeth_GostR3410_2012_256,
121         &ameth_GostR3410_2012_256,
122         "GOST2012_256",
123         "GOST R 34.10-2012 with 256 bit key",
124     },
125     {
126         NID_id_GostR3410_2012_512,
127         &pmeth_GostR3410_2012_512,
128         &ameth_GostR3410_2012_512,
129         "GOST2012_512",
130         "GOST R 34.10-2012 with 512 bit key",
131     },
132     {
133         NID_gost_mac_12,
134         &pmeth_Gost28147_MAC_12,
135         &ameth_Gost28147_MAC_12,
136         "GOST-MAC-12",
137         "GOST 28147-89 MAC with 2012 params",
138     },
139     {
140         NID_magma_mac,
141         &pmeth_magma_mac,
142         &ameth_magma_mac,
143         "MAGMA-MAC",
144         "GOST R 34.13-2015 Magma MAC",
145     },
146     {
147         NID_grasshopper_mac,
148         &pmeth_grasshopper_mac,
149         &ameth_grasshopper_mac,
150         "KUZNYECHIK-MAC",
151         "GOST R 34.13-2015 Grasshopper MAC",
152     },
153     {
154         NID_id_tc26_cipher_gostr3412_2015_magma_ctracpkm_omac,
155         &pmeth_magma_mac_acpkm,
156         &ameth_magma_mac_acpkm,
157         "ID-TC26-CIPHER-GOSTR3412-2015-MAGMA-CTRACPKM-OMAC",
158         "GOST R 34.13-2015 Magma MAC ACPKM",
159     },
160     {
161         NID_id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm_omac,
162         &pmeth_grasshopper_mac_acpkm,
163         &ameth_grasshopper_mac_acpkm,
164         "ID-TC26-CIPHER-GOSTR3412-2015-KUZNYECHIK-CTRACPKM-OMAC",
165         "GOST R 34.13-2015 Grasshopper MAC ACPKM",
166     },
167     { 0 },
168 };
169
170 #ifndef OSSL_NELEM
171 # define OSSL_NELEM(x) (sizeof(x)/sizeof((x)[0]))
172 #endif
173
174 static int known_digest_nids[OSSL_NELEM(gost_digest_array)];
175 static int known_cipher_nids[OSSL_NELEM(gost_cipher_array)];
176 /* `- 1' because of terminating zero element */
177 static int known_meths_nids[OSSL_NELEM(gost_meth_array) - 1];
178
179 static int gost_engine_init(ENGINE* e) {
180     return 1;
181 }
182
183 static int gost_engine_finish(ENGINE* e) {
184     return 1;
185 }
186
187 static int gost_engine_destroy(ENGINE* e) {
188     int i;
189
190     for (i = 0; i < OSSL_NELEM(gost_digest_array); i++)
191         GOST_deinit_digest(gost_digest_array[i]);
192     for (i = 0; i < OSSL_NELEM(gost_cipher_array); i++)
193         GOST_deinit_cipher(gost_cipher_array[i]);
194
195     gost_param_free();
196
197     struct gost_meth_minfo *minfo = gost_meth_array;
198     for (; minfo->nid; minfo++) {
199         *minfo->pmeth = NULL;
200         *minfo->ameth = NULL;
201     }
202
203     ERR_unload_GOST_strings();
204
205     return 1;
206 }
207
208 static int bind_gost(ENGINE* e, const char* id) {
209     int ret = 0;
210     if (id != NULL && strcmp(id, engine_gost_id) != 0)
211         return 0;
212     if (ameth_GostR3410_2001) {
213         printf("GOST engine already loaded\n");
214         goto end;
215     }
216     if (!ENGINE_set_id(e, engine_gost_id)) {
217         printf("ENGINE_set_id failed\n");
218         goto end;
219     }
220     if (!ENGINE_set_name(e, engine_gost_name)) {
221         printf("ENGINE_set_name failed\n");
222         goto end;
223     }
224     if (!ENGINE_set_digests(e, gost_digests)) {
225         printf("ENGINE_set_digests failed\n");
226         goto end;
227     }
228     if (!ENGINE_set_ciphers(e, gost_ciphers)) {
229         printf("ENGINE_set_ciphers failed\n");
230         goto end;
231     }
232     if (!ENGINE_set_pkey_meths(e, gost_pkey_meths)) {
233         printf("ENGINE_set_pkey_meths failed\n");
234         goto end;
235     }
236     if (!ENGINE_set_pkey_asn1_meths(e, gost_pkey_asn1_meths)) {
237         printf("ENGINE_set_pkey_asn1_meths failed\n");
238         goto end;
239     }
240     /* Control function and commands */
241     if (!ENGINE_set_cmd_defns(e, gost_cmds)) {
242         fprintf(stderr, "ENGINE_set_cmd_defns failed\n");
243         goto end;
244     }
245     if (!ENGINE_set_ctrl_function(e, gost_control_func)) {
246         fprintf(stderr, "ENGINE_set_ctrl_func failed\n");
247         goto end;
248     }
249     if (!ENGINE_set_destroy_function(e, gost_engine_destroy)
250         || !ENGINE_set_init_function(e, gost_engine_init)
251         || !ENGINE_set_finish_function(e, gost_engine_finish)) {
252         goto end;
253     }
254
255     struct gost_meth_minfo *minfo = gost_meth_array;
256     for (; minfo->nid; minfo++) {
257
258         /* This skip looks temporary. */
259         if (minfo->nid == NID_id_tc26_cipher_gostr3412_2015_magma_ctracpkm_omac)
260             continue;
261
262         if (!register_ameth_gost(minfo->nid, minfo->ameth, minfo->pemstr,
263                 minfo->info))
264             goto end;
265         if (!register_pmeth_gost(minfo->nid, minfo->pmeth, 0))
266             goto end;
267     }
268
269     if (!ENGINE_register_ciphers(e)
270         || !ENGINE_register_digests(e)
271         || !ENGINE_register_pkey_meths(e))
272         goto end;
273
274     int i;
275     for (i = 0; i < OSSL_NELEM(gost_cipher_array); i++) {
276         if (!EVP_add_cipher(GOST_init_cipher(gost_cipher_array[i])))
277             goto end;
278     }
279
280     for (i = 0; i < OSSL_NELEM(gost_digest_array); i++) {
281         if (!EVP_add_digest(GOST_init_digest(gost_digest_array[i])))
282             goto end;
283     }
284
285     ENGINE_register_all_complete();
286
287     ERR_load_GOST_strings();
288     ret = 1;
289     end:
290     return ret;
291 }
292
293 #ifndef OPENSSL_NO_DYNAMIC_ENGINE
294 IMPLEMENT_DYNAMIC_BIND_FN(bind_gost)
295     IMPLEMENT_DYNAMIC_CHECK_FN()
296 #endif                          /* ndef OPENSSL_NO_DYNAMIC_ENGINE */
297
298 /* ENGINE_DIGESTS_PTR callback installed by ENGINE_set_digests */
299 static int gost_digests(ENGINE *e, const EVP_MD **digest,
300                         const int **nids, int nid)
301 {
302     int i;
303
304     if (!digest) {
305         int *n = known_digest_nids;
306
307         *nids = n;
308         for (i = 0; i < OSSL_NELEM(gost_digest_array); i++)
309             *n++ = gost_digest_array[i]->nid;
310         return i;
311     }
312
313     for (i = 0; i < OSSL_NELEM(gost_digest_array); i++)
314         if (nid == gost_digest_array[i]->nid) {
315             *digest = GOST_init_digest(gost_digest_array[i]);
316             return 1;
317         }
318     *digest = NULL;
319     return 0;
320 }
321
322 /* ENGINE_CIPHERS_PTR callback installed by ENGINE_set_ciphers */
323 static int gost_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
324                         const int **nids, int nid)
325 {
326     int i;
327
328     if (!cipher) {
329         int *n = known_cipher_nids;
330
331         *nids = n;
332         for (i = 0; i < OSSL_NELEM(gost_cipher_array); i++)
333             *n++ = gost_cipher_array[i]->nid;
334         return i;
335     }
336
337     for (i = 0; i < OSSL_NELEM(gost_cipher_array); i++)
338         if (nid == gost_cipher_array[i]->nid) {
339             *cipher = GOST_init_cipher(gost_cipher_array[i]);
340             return 1;
341         }
342     *cipher = NULL;
343     return 0;
344 }
345
346 static int gost_meth_nids(const int **nids)
347 {
348     struct gost_meth_minfo *info = gost_meth_array;
349     int *n = known_meths_nids;
350
351     *nids = n;
352     for (; info->nid; info++)
353         *n++ = info->nid;
354     return OSSL_NELEM(known_meths_nids);
355 }
356
357 /* ENGINE_PKEY_METHS_PTR installed by ENGINE_set_pkey_meths */
358 static int gost_pkey_meths(ENGINE *e, EVP_PKEY_METHOD **pmeth,
359                            const int **nids, int nid)
360 {
361     struct gost_meth_minfo *info;
362
363     if (!pmeth)
364         return gost_meth_nids(nids);
365
366     for (info = gost_meth_array; info->nid; info++)
367         if (nid == info->nid) {
368             *pmeth = *info->pmeth;
369             return 1;
370         }
371     *pmeth = NULL;
372     return 0;
373 }
374
375 /* ENGINE_PKEY_ASN1_METHS_PTR installed by ENGINE_set_pkey_asn1_meths */
376 static int gost_pkey_asn1_meths(ENGINE *e, EVP_PKEY_ASN1_METHOD **ameth,
377                                 const int **nids, int nid)
378 {
379     struct gost_meth_minfo *info;
380
381     if (!ameth)
382         return gost_meth_nids(nids);
383
384     for (info = gost_meth_array; info->nid; info++)
385         if (nid == info->nid) {
386             *ameth = *info->ameth;
387             return 1;
388         }
389     *ameth = NULL;
390     return 0;
391 }
392
393 #ifdef OPENSSL_NO_DYNAMIC_ENGINE
394
395 static ENGINE* engine_gost(void) {
396     ENGINE* ret = ENGINE_new();
397     if (!ret)
398         return NULL;
399     if (!bind_gost(ret, engine_gost_id)) {
400         ENGINE_free(ret);
401         return NULL;
402     }
403     return ret;
404 }
405
406 void ENGINE_load_gost(void) {
407     ENGINE* toadd;
408     if (pmeth_GostR3410_2001)
409         return;
410     toadd = engine_gost();
411     if (!toadd)
412         return;
413     ENGINE_add(toadd);
414     ENGINE_free(toadd);
415     ERR_clear_error();
416 }
417
418 #endif
419 /* vim: set expandtab cinoptions=\:0,l1,t0,g0,(0 sw=4 : */