]> www.wagner.pp.ru Git - openssl-gost/engine.git/blob - gost_pmeth.c
9c1d602c303ba030196775ef357ebd6868b4624b
[openssl-gost/engine.git] / gost_pmeth.c
1 /**********************************************************************
2  *                          gost_pmeth.c                              *
3  *             Copyright (c) 2005-2013 Cryptocom LTD                  *
4  *         This file is distributed under the same license as OpenSSL *
5  *                                                                    *
6  *   Implementation of RFC 4357 (GOST R 34.10) Publick key method     *
7  *       for OpenSSL                                                  *
8  *          Requires OpenSSL 1.0.0+ for compilation                   *
9  **********************************************************************/
10 #include <openssl/evp.h>
11 #include <openssl/objects.h>
12 #include <openssl/ec.h>
13 #include <openssl/err.h>
14 #include <openssl/x509v3.h>     /* For string_to_hex */
15 #include <openssl/opensslv.h>   /* For OPENSSL_VERSION_MAJOR */
16 #include <stdlib.h>
17 #include <string.h>
18 #include <ctype.h>
19 #include "gost_lcl.h"
20 #include "e_gost_err.h"
21
22 #define ossl3_const
23 #ifdef OPENSSL_VERSION_MAJOR
24 #undef ossl3_const
25 #define ossl3_const const
26 #endif
27
28 /* -----init, cleanup, copy - uniform for all algs  --------------*/
29 /* Allocates new gost_pmeth_data structure and assigns it as data */
30 static int pkey_gost_init(EVP_PKEY_CTX *ctx)
31 {
32     struct gost_pmeth_data *data;
33     EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx);
34
35     data = OPENSSL_malloc(sizeof(*data));
36     if (!data)
37         return 0;
38     memset(data, 0, sizeof(*data));
39     if (pkey && EVP_PKEY_get0(pkey)) {
40         switch (EVP_PKEY_base_id(pkey)) {
41         case NID_id_GostR3410_2001:
42         case NID_id_GostR3410_2012_256:
43         case NID_id_GostR3410_2012_512:
44             {
45                 const EC_GROUP *group =
46                     EC_KEY_get0_group(EVP_PKEY_get0((EVP_PKEY *)pkey));
47                 if (group != NULL) {
48                     data->sign_param_nid = EC_GROUP_get_curve_name(group);
49                     break;
50                 }
51                 /* else */
52             }
53         default:
54             OPENSSL_free(data);
55             return 0;
56         }
57     }
58     EVP_PKEY_CTX_set_data(ctx, data);
59     return 1;
60 }
61
62 /* Copies contents of gost_pmeth_data structure */
63 static int pkey_gost_copy(EVP_PKEY_CTX *dst, ossl3_const EVP_PKEY_CTX *src)
64 {
65     struct gost_pmeth_data *dst_data, *src_data;
66     if (!pkey_gost_init(dst)) {
67         return 0;
68     }
69     src_data = EVP_PKEY_CTX_get_data(src);
70     dst_data = EVP_PKEY_CTX_get_data(dst);
71     if (!src_data || !dst_data)
72         return 0;
73
74     *dst_data = *src_data;
75
76     return 1;
77 }
78
79 /* Frees up gost_pmeth_data structure */
80 static void pkey_gost_cleanup(EVP_PKEY_CTX *ctx)
81 {
82     struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
83     if (!data)
84         return;
85     OPENSSL_free(data);
86 }
87
88 /* --------------------- control functions  ------------------------------*/
89 static int pkey_gost_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
90 {
91     struct gost_pmeth_data *pctx =
92         (struct gost_pmeth_data *)EVP_PKEY_CTX_get_data(ctx);
93     if (pctx == NULL)
94         return 0;
95
96     switch (type) {
97     case EVP_PKEY_CTRL_MD:
98         {
99             EVP_PKEY *key = EVP_PKEY_CTX_get0_pkey(ctx);
100             int pkey_nid = (key == NULL) ? NID_undef : EVP_PKEY_base_id(key);
101
102             OPENSSL_assert(p2 != NULL);
103
104             switch (EVP_MD_type((const EVP_MD *)p2)) {
105             case NID_id_GostR3411_94:
106                 if (pkey_nid == NID_id_GostR3410_2001
107                     || pkey_nid == NID_id_GostR3410_94) {
108                     pctx->md = (EVP_MD *)p2;
109                     return 1;
110                 }
111                 break;
112
113             case NID_id_GostR3411_2012_256:
114                 if (pkey_nid == NID_id_GostR3410_2012_256) {
115                     pctx->md = (EVP_MD *)p2;
116                     return 1;
117                 }
118                 break;
119
120             case NID_id_GostR3411_2012_512:
121                 if (pkey_nid == NID_id_GostR3410_2012_512) {
122                     pctx->md = (EVP_MD *)p2;
123                     return 1;
124                 }
125                 break;
126             }
127
128             GOSTerr(GOST_F_PKEY_GOST_CTRL, GOST_R_INVALID_DIGEST_TYPE);
129             return 0;
130         }
131
132     case EVP_PKEY_CTRL_GET_MD:
133         *(const EVP_MD **)p2 = pctx->md;
134         return 1;
135
136     case EVP_PKEY_CTRL_PKCS7_ENCRYPT:
137     case EVP_PKEY_CTRL_PKCS7_DECRYPT:
138     case EVP_PKEY_CTRL_PKCS7_SIGN:
139     case EVP_PKEY_CTRL_DIGESTINIT:
140 #ifndef OPENSSL_NO_CMS
141     case EVP_PKEY_CTRL_CMS_ENCRYPT:
142     case EVP_PKEY_CTRL_CMS_DECRYPT:
143     case EVP_PKEY_CTRL_CMS_SIGN:
144 #endif
145         return 1;
146
147     case EVP_PKEY_CTRL_GOST_PARAMSET:
148         pctx->sign_param_nid = (int)p1;
149         return 1;
150     case EVP_PKEY_CTRL_SET_IV:
151         if (p1 > sizeof(pctx->shared_ukm) || !p2) {
152             GOSTerr(GOST_F_PKEY_GOST_CTRL, GOST_R_UKM_NOT_SET);
153             return 0;
154         }
155         memcpy(pctx->shared_ukm, p2, (int)p1);
156         pctx->shared_ukm_size = p1;
157         return 1;
158     case EVP_PKEY_CTRL_SET_VKO:
159         switch (p1) {
160             case 0: /* switch to KEG */
161             case NID_id_GostR3411_2012_256:
162             case NID_id_GostR3411_2012_512:
163                 break;
164             default:
165                 GOSTerr(GOST_F_PKEY_GOST_CTRL, GOST_R_INVALID_DIGEST_TYPE);
166                 return 0;
167         }
168         pctx->vko_dgst_nid = p1;
169         return 1;
170   case EVP_PKEY_CTRL_CIPHER:
171         switch (p1) {
172           case NID_magma_ctr_acpkm:
173           case NID_magma_ctr_acpkm_omac:
174           case NID_magma_ctr:
175             pctx->cipher_nid = NID_magma_ctr;
176             return 1;
177           case NID_kuznyechik_ctr_acpkm:
178           case NID_kuznyechik_ctr_acpkm_omac:
179           case NID_kuznyechik_ctr:
180             pctx->cipher_nid = NID_kuznyechik_ctr;
181             return 1;
182           default:
183             pctx->cipher_nid = p1;
184             return 1;
185         }
186         return 1;
187     case EVP_PKEY_CTRL_PEER_KEY:
188         if (p1 == 0 || p1 == 1) /* call from EVP_PKEY_derive_set_peer */
189             return 1;
190         if (p1 == 2)            /* TLS: peer key used? */
191             return pctx->peer_key_used;
192         if (p1 == 3)            /* TLS: peer key used! */
193             return (pctx->peer_key_used = 1);
194         break;
195     }
196
197     GOSTerr(GOST_F_PKEY_GOST_CTRL, GOST_R_CTRL_CALL_FAILED);
198     return -2;
199 }
200
201 static int pkey_gost_ec_ctrl_str_common(EVP_PKEY_CTX *ctx,
202                                      const char *type, const char *value)
203 {
204   if (0 == strcmp(type, ukm_ctrl_string)) {
205     unsigned char ukm_buf[32], *tmp = NULL;
206     long len = 0;
207     tmp = OPENSSL_hexstr2buf(value, &len);
208     if (tmp == NULL)
209       return 0;
210
211     if (len > 32) {
212       OPENSSL_free(tmp);
213       GOSTerr(GOST_F_PKEY_GOST_EC_CTRL_STR_COMMON, GOST_R_CTRL_CALL_FAILED);
214       return 0;
215     }
216     memcpy(ukm_buf, tmp, len);
217     OPENSSL_free(tmp);
218
219     return pkey_gost_ctrl(ctx, EVP_PKEY_CTRL_SET_IV, len, ukm_buf);
220   } else if (strcmp(type, vko_ctrl_string) == 0) {
221       int bits = atoi(value);
222       int vko_dgst_nid = 0;
223
224       if (bits == 256)
225           vko_dgst_nid = NID_id_GostR3411_2012_256;
226       else if (bits == 512)
227           vko_dgst_nid = NID_id_GostR3411_2012_512;
228       else if (bits != 0) {
229           GOSTerr(GOST_F_PKEY_GOST_EC_CTRL_STR_COMMON, GOST_R_INVALID_DIGEST_TYPE);
230           return 0;
231       }
232       return pkey_gost_ctrl(ctx, EVP_PKEY_CTRL_SET_VKO, vko_dgst_nid, NULL);
233   }
234   return -2;
235 }
236
237 static int pkey_gost_ec_ctrl_str_256(EVP_PKEY_CTX *ctx,
238                                      const char *type, const char *value)
239 {
240     if (strcmp(type, param_ctrl_string) == 0) {
241         int param_nid = 0;
242
243         if (!value) {
244             return 0;
245         }
246         if (strlen(value) == 1) {
247             switch (toupper((unsigned char)value[0])) {
248             case 'A':
249                 param_nid = NID_id_GostR3410_2001_CryptoPro_A_ParamSet;
250                 break;
251             case 'B':
252                 param_nid = NID_id_GostR3410_2001_CryptoPro_B_ParamSet;
253                 break;
254             case 'C':
255                 param_nid = NID_id_GostR3410_2001_CryptoPro_C_ParamSet;
256                 break;
257             case '0':
258                 param_nid = NID_id_GostR3410_2001_TestParamSet;
259                 break;
260             default:
261                 return 0;
262             }
263         } else if ((strlen(value) == 2)
264                    && (toupper((unsigned char)value[0]) == 'X')) {
265             switch (toupper((unsigned char)value[1])) {
266             case 'A':
267                 param_nid = NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet;
268                 break;
269             case 'B':
270                 param_nid = NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet;
271                 break;
272             default:
273                 return 0;
274             }
275     } else if ((strlen(value) == 3)
276         && (toupper((unsigned char)value[0]) == 'T')
277         && (toupper((unsigned char)value[1]) == 'C')) {
278             switch (toupper((unsigned char)value[2])) {
279             case 'A':
280                 param_nid = NID_id_tc26_gost_3410_2012_256_paramSetA;
281                 break;
282             case 'B':
283                 param_nid = NID_id_tc26_gost_3410_2012_256_paramSetB;
284                 break;
285             case 'C':
286                 param_nid = NID_id_tc26_gost_3410_2012_256_paramSetC;
287                 break;
288             case 'D':
289                 param_nid = NID_id_tc26_gost_3410_2012_256_paramSetD;
290                 break;
291             default:
292                 return 0;
293             }
294         } else {
295             R3410_ec_params *p = R3410_2001_paramset;
296             param_nid = OBJ_txt2nid(value);
297             if (param_nid == NID_undef) {
298                 return 0;
299             }
300             for (; p->nid != NID_undef; p++) {
301                 if (p->nid == param_nid)
302                     break;
303             }
304             if (p->nid == NID_undef) {
305                 GOSTerr(GOST_F_PKEY_GOST_EC_CTRL_STR_256,
306                         GOST_R_INVALID_PARAMSET);
307                 return 0;
308             }
309         }
310
311         return pkey_gost_ctrl(ctx, EVP_PKEY_CTRL_GOST_PARAMSET,
312                               param_nid, NULL);
313     }
314
315     return pkey_gost_ec_ctrl_str_common(ctx, type, value);
316 }
317
318 static int pkey_gost_ec_ctrl_str_512(EVP_PKEY_CTX *ctx,
319                                      const char *type, const char *value)
320 {
321     int param_nid = NID_undef;
322
323     if (strcmp(type, param_ctrl_string))
324       return pkey_gost_ec_ctrl_str_common(ctx, type, value);
325
326     if (!value)
327         return 0;
328
329     if (strlen(value) == 1) {
330         switch (toupper((unsigned char)value[0])) {
331         case 'A':
332             param_nid = NID_id_tc26_gost_3410_2012_512_paramSetA;
333             break;
334
335         case 'B':
336             param_nid = NID_id_tc26_gost_3410_2012_512_paramSetB;
337             break;
338
339         case 'C':
340             param_nid = NID_id_tc26_gost_3410_2012_512_paramSetC;
341             break;
342
343         default:
344             return 0;
345         }
346     } else {
347         R3410_ec_params *p = R3410_2012_512_paramset;
348         param_nid = OBJ_txt2nid(value);
349         if (param_nid == NID_undef)
350             return 0;
351
352         while (p->nid != NID_undef && p->nid != param_nid)
353             p++;
354
355         if (p->nid == NID_undef) {
356             GOSTerr(GOST_F_PKEY_GOST_EC_CTRL_STR_512,
357                     GOST_R_INVALID_PARAMSET);
358             return 0;
359         }
360     }
361
362     return pkey_gost_ctrl(ctx, EVP_PKEY_CTRL_GOST_PARAMSET, param_nid, NULL);
363 }
364
365 /* --------------------- key generation  --------------------------------*/
366
367 static int pkey_gost_paramgen_init(EVP_PKEY_CTX *ctx)
368 {
369     return 1;
370 }
371
372 static int pkey_gost2001_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
373 {
374     struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
375     EC_KEY *ec = NULL;
376
377     if (!data || data->sign_param_nid == NID_undef) {
378         GOSTerr(GOST_F_PKEY_GOST2001_PARAMGEN, GOST_R_NO_PARAMETERS_SET);
379         return 0;
380     }
381
382     ec = EC_KEY_new();
383     if (!fill_GOST_EC_params(ec, data->sign_param_nid)
384         || !EVP_PKEY_assign(pkey, NID_id_GostR3410_2001, ec)) {
385         EC_KEY_free(ec);
386         return 0;
387     }
388     return 1;
389 }
390
391 static int pkey_gost2012_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
392 {
393     struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
394     EC_KEY *ec;
395     int result = 0;
396
397     if (!data || data->sign_param_nid == NID_undef) {
398         GOSTerr(GOST_F_PKEY_GOST2012_PARAMGEN, GOST_R_NO_PARAMETERS_SET);
399         return 0;
400     }
401
402     ec = EC_KEY_new();
403     if (!fill_GOST_EC_params(ec, data->sign_param_nid)) {
404         EC_KEY_free(ec);
405         return 0;
406     }
407
408     switch (data->sign_param_nid) {
409     case NID_id_tc26_gost_3410_2012_512_paramSetA:
410     case NID_id_tc26_gost_3410_2012_512_paramSetB:
411     case NID_id_tc26_gost_3410_2012_512_paramSetC:
412     case NID_id_tc26_gost_3410_2012_512_paramSetTest:
413         result =
414             (EVP_PKEY_assign(pkey, NID_id_GostR3410_2012_512, ec)) ? 1 : 0;
415         break;
416
417     case NID_id_GostR3410_2001_CryptoPro_A_ParamSet:
418     case NID_id_GostR3410_2001_CryptoPro_B_ParamSet:
419     case NID_id_GostR3410_2001_CryptoPro_C_ParamSet:
420     case NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet:
421     case NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet:
422     case NID_id_GostR3410_2001_TestParamSet:
423     case NID_id_tc26_gost_3410_2012_256_paramSetA:
424     case NID_id_tc26_gost_3410_2012_256_paramSetB:
425     case NID_id_tc26_gost_3410_2012_256_paramSetC:
426     case NID_id_tc26_gost_3410_2012_256_paramSetD:
427         result =
428             (EVP_PKEY_assign(pkey, NID_id_GostR3410_2012_256, ec)) ? 1 : 0;
429         break;
430     default:
431         result = 0;
432         break;
433     }
434
435     if (result == 0)
436         EC_KEY_free(ec);
437
438     return result;
439 }
440
441 /* ----------- keygen callbacks --------------------------------------*/
442 /* Generates GOST_R3410 2001 key and assigns it using specified type */
443 static int pkey_gost2001cp_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
444 {
445     EC_KEY *ec;
446     if (!pkey_gost2001_paramgen(ctx, pkey))
447         return 0;
448     ec = EVP_PKEY_get0(pkey);
449     gost_ec_keygen(ec);
450     return 1;
451 }
452
453 /* Generates GOST_R3410 2012 key and assigns it using specified type */
454 static int pkey_gost2012cp_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
455 {
456     if (!pkey_gost2012_paramgen(ctx, pkey))
457         return 0;
458
459     gost_ec_keygen(EVP_PKEY_get0(pkey));
460     return 1;
461 }
462
463 /* ----------- sign callbacks --------------------------------------*/
464 /*
465  * Packs signature according to Cryptopro rules
466  * and frees up ECDSA_SIG structure
467  */
468 int pack_sign_cp(ECDSA_SIG *s, int order, unsigned char *sig, size_t *siglen)
469 {
470     const BIGNUM *sig_r = NULL, *sig_s = NULL;
471     ECDSA_SIG_get0(s, &sig_r, &sig_s);
472     *siglen = 2 * order;
473     memset(sig, 0, *siglen);
474     store_bignum(sig_s, sig, order);
475     store_bignum(sig_r, sig + order, order);
476     ECDSA_SIG_free(s);
477     return 1;
478 }
479
480 static int pkey_gost_ec_cp_sign(EVP_PKEY_CTX *ctx, unsigned char *sig,
481                                 size_t *siglen, const unsigned char *tbs,
482                                 size_t tbs_len)
483 {
484     ECDSA_SIG *unpacked_sig = NULL;
485     EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx);
486     int order = 0;
487
488     if (!siglen)
489         return 0;
490     if (!pkey)
491         return 0;
492
493     switch (EVP_PKEY_base_id(pkey)) {
494     case NID_id_GostR3410_2001:
495     case NID_id_GostR3410_2012_256:
496         order = 64;
497         break;
498     case NID_id_GostR3410_2012_512:
499         order = 128;
500         break;
501     default:
502         return 0;
503     }
504
505     if (!sig) {
506         *siglen = order;
507         return 1;
508     }
509     unpacked_sig = gost_ec_sign(tbs, tbs_len, EVP_PKEY_get0(pkey));
510     if (!unpacked_sig) {
511         return 0;
512     }
513     return pack_sign_cp(unpacked_sig, order / 2, sig, siglen);
514 }
515
516 /* ------------------- verify callbacks ---------------------------*/
517 /* Unpack signature according to cryptopro rules  */
518 ECDSA_SIG *unpack_cp_signature(const unsigned char *sigbuf, size_t siglen)
519 {
520     ECDSA_SIG *sig;
521     BIGNUM *r = NULL, *s = NULL;
522
523     sig = ECDSA_SIG_new();
524     if (sig == NULL) {
525         GOSTerr(GOST_F_UNPACK_CP_SIGNATURE, ERR_R_MALLOC_FAILURE);
526         return NULL;
527     }
528     s = BN_bin2bn(sigbuf, siglen / 2, NULL);
529     r = BN_bin2bn(sigbuf + siglen / 2, siglen / 2, NULL);
530     ECDSA_SIG_set0(sig, r, s);
531     return sig;
532 }
533
534 static int pkey_gost_ec_cp_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig,
535                                   size_t siglen, const unsigned char *tbs,
536                                   size_t tbs_len)
537 {
538     int ok = 0;
539     EVP_PKEY *pub_key = EVP_PKEY_CTX_get0_pkey(ctx);
540     ECDSA_SIG *s = (sig) ? unpack_cp_signature(sig, siglen) : NULL;
541     if (!s)
542         return 0;
543 #ifdef DEBUG_SIGN
544     fprintf(stderr, "R=");
545     BN_print_fp(stderr, ECDSA_SIG_get0_r(s));
546     fprintf(stderr, "\nS=");
547     BN_print_fp(stderr, ECDSA_SIG_get0_s(s));
548     fprintf(stderr, "\n");
549 #endif
550     if (pub_key)
551         ok = gost_ec_verify(tbs, tbs_len, s, EVP_PKEY_get0(pub_key));
552     ECDSA_SIG_free(s);
553     return ok;
554 }
555
556 /* ------------- encrypt init -------------------------------------*/
557 /* Generates ephermeral key */
558 static int pkey_gost_encrypt_init(EVP_PKEY_CTX *ctx)
559 {
560     return 1;
561 }
562
563 /* --------------- Derive init ------------------------------------*/
564 static int pkey_gost_derive_init(EVP_PKEY_CTX *ctx)
565 {
566     return 1;
567 }
568
569 /* -------- PKEY_METHOD for GOST MAC algorithm --------------------*/
570 static int pkey_gost_mac_init(EVP_PKEY_CTX *ctx)
571 {
572     struct gost_mac_pmeth_data *data = OPENSSL_malloc(sizeof(*data));
573     EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx);
574
575     if (!data)
576         return 0;
577     memset(data, 0, sizeof(*data));
578     data->mac_size = 4;
579     data->mac_param_nid = NID_undef;
580
581     if (pkey) {
582         struct gost_mac_key *key = EVP_PKEY_get0(pkey);
583         if (key) {
584             data->mac_param_nid = key->mac_param_nid;
585             data->mac_size = key->mac_size;
586         }
587     }
588
589     EVP_PKEY_CTX_set_data(ctx, data);
590     return 1;
591 }
592
593 static int pkey_gost_omac_init(EVP_PKEY_CTX *ctx, size_t mac_size)
594 {
595     struct gost_mac_pmeth_data *data = OPENSSL_malloc(sizeof(*data));
596     EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx);
597
598     if (!data)
599         return 0;
600     memset(data, 0, sizeof(*data));
601     data->mac_size = mac_size;
602     data->mac_param_nid = NID_undef;
603
604     if (pkey) {
605         struct gost_mac_key *key = EVP_PKEY_get0(pkey);
606         if (key) {
607             data->mac_param_nid = key->mac_param_nid;
608             data->mac_size = key->mac_size;
609         }
610     }
611
612     EVP_PKEY_CTX_set_data(ctx, data);
613     return 1;
614 }
615
616 static int pkey_gost_magma_mac_init(EVP_PKEY_CTX *ctx)
617 {
618     return pkey_gost_omac_init(ctx, 8);
619 }
620
621 static int pkey_gost_grasshopper_mac_init(EVP_PKEY_CTX *ctx)
622 {
623     return pkey_gost_omac_init(ctx, 16);
624 }
625
626 static void pkey_gost_mac_cleanup(EVP_PKEY_CTX *ctx)
627 {
628     struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
629     if (data)
630         OPENSSL_free(data);
631 }
632
633 static int pkey_gost_mac_copy(EVP_PKEY_CTX *dst, ossl3_const EVP_PKEY_CTX *src)
634 {
635     struct gost_mac_pmeth_data *dst_data, *src_data;
636     if (!pkey_gost_mac_init(dst)) {
637         return 0;
638     }
639     src_data = EVP_PKEY_CTX_get_data(src);
640     dst_data = EVP_PKEY_CTX_get_data(dst);
641     if (!src_data || !dst_data)
642         return 0;
643
644     *dst_data = *src_data;
645     return 1;
646 }
647
648 static int pkey_gost_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
649 {
650     struct gost_mac_pmeth_data *data =
651         (struct gost_mac_pmeth_data *)EVP_PKEY_CTX_get_data(ctx);
652
653     switch (type) {
654     case EVP_PKEY_CTRL_MD:
655         {
656             int nid = EVP_MD_type((const EVP_MD *)p2);
657             if (nid != NID_id_Gost28147_89_MAC && nid != NID_gost_mac_12) {
658                 GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL,
659                         GOST_R_INVALID_DIGEST_TYPE);
660                 return 0;
661             }
662             data->md = (EVP_MD *)p2;
663             return 1;
664         }
665
666     case EVP_PKEY_CTRL_GET_MD:
667         *(const EVP_MD **)p2 = data->md;
668         return 1;
669
670     case EVP_PKEY_CTRL_PKCS7_ENCRYPT:
671     case EVP_PKEY_CTRL_PKCS7_DECRYPT:
672     case EVP_PKEY_CTRL_PKCS7_SIGN:
673         return 1;
674     case EVP_PKEY_CTRL_SET_MAC_KEY:
675         if (p1 != 32) {
676             GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL, GOST_R_INVALID_MAC_KEY_LENGTH);
677             return 0;
678         }
679
680         memcpy(data->key, p2, 32);
681         data->key_set = 1;
682         return 1;
683     case EVP_PKEY_CTRL_GOST_PARAMSET:
684         {
685             struct gost_cipher_info *param = p2;
686             data->mac_param_nid = param->nid;
687             return 1;
688         }
689     case EVP_PKEY_CTRL_DIGESTINIT:
690         {
691             EVP_MD_CTX *mctx = p2;
692             if (!data->key_set) {
693                 struct gost_mac_key *key;
694                 EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx);
695                 if (!pkey) {
696                     GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL,
697                             GOST_R_MAC_KEY_NOT_SET);
698                     return 0;
699                 }
700                 key = EVP_PKEY_get0(pkey);
701                 if (!key) {
702                     GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL,
703                             GOST_R_MAC_KEY_NOT_SET);
704                     return 0;
705                 }
706                 return EVP_MD_meth_get_ctrl(EVP_MD_CTX_md(mctx))
707                     (mctx, EVP_MD_CTRL_SET_KEY, 0, key);
708             } else {
709                 return EVP_MD_meth_get_ctrl(EVP_MD_CTX_md(mctx))
710                     (mctx, EVP_MD_CTRL_SET_KEY, 32, &(data->key));
711             }
712         }
713     case EVP_PKEY_CTRL_MAC_LEN:
714         {
715             if (p1 < 1 || p1 > 8) {
716
717                 GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL, GOST_R_INVALID_MAC_SIZE);
718                 return 0;
719             }
720             data->mac_size = p1;
721             return 1;
722         }
723     }
724     return -2;
725 }
726
727 static int pkey_gost_mac_ctrl_str(EVP_PKEY_CTX *ctx,
728                                   const char *type, const char *value)
729 {
730     if (strcmp(type, key_ctrl_string) == 0) {
731         if (strlen(value) != 32) {
732             GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL_STR,
733                     GOST_R_INVALID_MAC_KEY_LENGTH);
734             return 0;
735         }
736         return pkey_gost_mac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY,
737                                   32, (char *)value);
738     }
739     if (strcmp(type, hexkey_ctrl_string) == 0) {
740         long keylen;
741         int ret;
742         unsigned char *keybuf = string_to_hex(value, &keylen);
743         if (!keybuf || keylen != 32) {
744             GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL_STR,
745                     GOST_R_INVALID_MAC_KEY_LENGTH);
746             OPENSSL_free(keybuf);
747             return 0;
748         }
749         ret = pkey_gost_mac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, 32, keybuf);
750         OPENSSL_free(keybuf);
751         return ret;
752
753     }
754     if (!strcmp(type, maclen_ctrl_string)) {
755         char *endptr;
756         long size = strtol(value, &endptr, 10);
757         if (*endptr != '\0') {
758             GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL_STR, GOST_R_INVALID_MAC_SIZE);
759             return 0;
760         }
761         return pkey_gost_mac_ctrl(ctx, EVP_PKEY_CTRL_MAC_LEN, size, NULL);
762     }
763     if (strcmp(type, param_ctrl_string) == 0) {
764         ASN1_OBJECT *obj = OBJ_txt2obj(value, 0);
765         const struct gost_cipher_info *param = NULL;
766         if (obj == NULL) {
767             GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL_STR, GOST_R_INVALID_MAC_PARAMS);
768             return 0;
769         }
770
771         param = get_encryption_params(obj);
772         ASN1_OBJECT_free(obj);
773         if (param == NULL) {
774             GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL_STR, GOST_R_INVALID_MAC_PARAMS);
775             return 0;
776         }
777
778
779         return pkey_gost_mac_ctrl(ctx, EVP_PKEY_CTRL_GOST_PARAMSET, 0,
780                                   (void *)param);
781     }
782     return -2;
783 }
784
785 static int pkey_gost_omac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2, size_t max_size)
786 {
787     struct gost_mac_pmeth_data *data =
788         (struct gost_mac_pmeth_data *)EVP_PKEY_CTX_get_data(ctx);
789
790     switch (type) {
791     case EVP_PKEY_CTRL_MD:
792         {
793             int nid = EVP_MD_type((const EVP_MD *)p2);
794             if (nid != NID_magma_mac && nid != NID_grasshopper_mac
795                 && nid != NID_id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm_omac /* FIXME beldmit */
796                 && nid != NID_id_tc26_cipher_gostr3412_2015_magma_ctracpkm_omac) {
797                 GOSTerr(GOST_F_PKEY_GOST_OMAC_CTRL,
798                         GOST_R_INVALID_DIGEST_TYPE);
799                 return 0;
800             }
801             data->md = (EVP_MD *)p2;
802             return 1;
803         }
804
805     case EVP_PKEY_CTRL_GET_MD:
806         *(const EVP_MD **)p2 = data->md;
807         return 1;
808
809     case EVP_PKEY_CTRL_PKCS7_ENCRYPT:
810     case EVP_PKEY_CTRL_PKCS7_DECRYPT:
811     case EVP_PKEY_CTRL_PKCS7_SIGN:
812         return 1;
813     case EVP_PKEY_CTRL_SET_MAC_KEY:
814         if (p1 != 32) {
815             GOSTerr(GOST_F_PKEY_GOST_OMAC_CTRL, GOST_R_INVALID_MAC_KEY_LENGTH);
816             return 0;
817         }
818
819         memcpy(data->key, p2, 32);
820         data->key_set = 1;
821         return 1;
822     case EVP_PKEY_CTRL_DIGESTINIT:
823         {
824             EVP_MD_CTX *mctx = p2;
825             if (!data->key_set) {
826                 struct gost_mac_key *key;
827                 EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx);
828                 if (!pkey) {
829                     GOSTerr(GOST_F_PKEY_GOST_OMAC_CTRL,
830                             GOST_R_MAC_KEY_NOT_SET);
831                     return 0;
832                 }
833                 key = EVP_PKEY_get0(pkey);
834                 if (!key) {
835                     GOSTerr(GOST_F_PKEY_GOST_OMAC_CTRL,
836                             GOST_R_MAC_KEY_NOT_SET);
837                     return 0;
838                 }
839                 return EVP_MD_meth_get_ctrl(EVP_MD_CTX_md(mctx))
840                     (mctx, EVP_MD_CTRL_SET_KEY, 0, key);
841             } else {
842                 return EVP_MD_meth_get_ctrl(EVP_MD_CTX_md(mctx))
843                     (mctx, EVP_MD_CTRL_SET_KEY, 32, &(data->key));
844             }
845         }
846     case EVP_PKEY_CTRL_MAC_LEN:
847         {
848             if (p1 < 1 || p1 > max_size) {
849
850                 GOSTerr(GOST_F_PKEY_GOST_OMAC_CTRL, GOST_R_INVALID_MAC_SIZE);
851                 return 0;
852             }
853             data->mac_size = p1;
854             return 1;
855         }
856     }
857     return -2;
858 }
859
860 static int pkey_gost_magma_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
861 {
862     return pkey_gost_omac_ctrl(ctx, type, p1, p2, 8);
863 }
864
865 static int pkey_gost_grasshopper_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
866 {
867     return pkey_gost_omac_ctrl(ctx, type, p1, p2, 16);
868 }
869
870 static int pkey_gost_omac_ctrl_str(EVP_PKEY_CTX *ctx,
871                                   const char *type, const char *value, size_t max_size)
872 {
873     if (strcmp(type, key_ctrl_string) == 0) {
874         if (strlen(value) != 32) {
875             GOSTerr(GOST_F_PKEY_GOST_OMAC_CTRL_STR,
876                     GOST_R_INVALID_MAC_KEY_LENGTH);
877             return 0;
878         }
879         return pkey_gost_mac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY,
880                                   32, (char *)value);
881     }
882     if (strcmp(type, hexkey_ctrl_string) == 0) {
883         long keylen;
884         int ret;
885         unsigned char *keybuf = string_to_hex(value, &keylen);
886         if (!keybuf || keylen != 32) {
887             GOSTerr(GOST_F_PKEY_GOST_OMAC_CTRL_STR,
888                     GOST_R_INVALID_MAC_KEY_LENGTH);
889             OPENSSL_free(keybuf);
890             return 0;
891         }
892         ret = pkey_gost_mac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, 32, keybuf);
893         OPENSSL_free(keybuf);
894         return ret;
895
896     }
897     if (!strcmp(type, maclen_ctrl_string)) {
898         char *endptr;
899         long size = strtol(value, &endptr, 10);
900         if (*endptr != '\0') {
901             GOSTerr(GOST_F_PKEY_GOST_OMAC_CTRL_STR, GOST_R_INVALID_MAC_SIZE);
902             return 0;
903         }
904         return pkey_gost_omac_ctrl(ctx, EVP_PKEY_CTRL_MAC_LEN, size, NULL, max_size);
905     }
906     return -2;
907 }
908
909 static int pkey_gost_magma_mac_ctrl_str(EVP_PKEY_CTX *ctx,
910                                   const char *type, const char *value)
911 {
912     return pkey_gost_omac_ctrl_str(ctx, type, value, 8);
913 }
914
915 static int pkey_gost_grasshopper_mac_ctrl_str(EVP_PKEY_CTX *ctx,
916                                   const char *type, const char *value)
917 {
918     return pkey_gost_omac_ctrl_str(ctx, type, value, 8);
919 }
920
921 static int pkey_gost_mac_keygen_base(EVP_PKEY_CTX *ctx,
922                                      EVP_PKEY *pkey, int mac_nid)
923 {
924     struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
925     struct gost_mac_key *keydata;
926     if (!data || !data->key_set) {
927         GOSTerr(GOST_F_PKEY_GOST_MAC_KEYGEN_BASE, GOST_R_MAC_KEY_NOT_SET);
928         return 0;
929     }
930     keydata = OPENSSL_malloc(sizeof(struct gost_mac_key));
931     if (keydata == NULL)
932         return 0;
933     memcpy(keydata->key, data->key, 32);
934     keydata->mac_param_nid = data->mac_param_nid;
935     keydata->mac_size = data->mac_size;
936     EVP_PKEY_assign(pkey, mac_nid, keydata);
937     return 1;
938 }
939
940 static int pkey_gost_mac_keygen_12(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
941 {
942     return pkey_gost_mac_keygen_base(ctx, pkey, NID_gost_mac_12);
943 }
944
945 static int pkey_gost_mac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
946 {
947     return pkey_gost_mac_keygen_base(ctx, pkey, NID_id_Gost28147_89_MAC);
948 }
949
950 static int pkey_gost_magma_mac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
951 {
952     return pkey_gost_mac_keygen_base(ctx, pkey, NID_magma_mac);
953 }
954
955 static int pkey_gost_grasshopper_mac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
956 {
957     return pkey_gost_mac_keygen_base(ctx, pkey, NID_grasshopper_mac);
958 }
959
960 static int pkey_gost_mac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
961 {
962     struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
963
964     if (data == NULL) {
965         pkey_gost_mac_init(ctx);
966     }
967
968     data = EVP_PKEY_CTX_get_data(ctx);
969     if (!data) {
970         GOSTerr(GOST_F_PKEY_GOST_MAC_SIGNCTX_INIT, GOST_R_MAC_KEY_NOT_SET);
971         return 0;
972     }
973
974     return 1;
975 }
976
977 static int pkey_gost_magma_mac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
978 {
979     struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
980
981     if (data == NULL) {
982         pkey_gost_omac_init(ctx, 4);
983     }
984
985     data = EVP_PKEY_CTX_get_data(ctx);
986     if (!data) {
987         GOSTerr(GOST_F_PKEY_GOST_MAGMA_MAC_SIGNCTX_INIT, GOST_R_MAC_KEY_NOT_SET);
988         return 0;
989     }
990
991     return 1;
992 }
993
994 static int pkey_gost_grasshopper_mac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
995 {
996     struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
997
998     if (data == NULL) {
999         pkey_gost_omac_init(ctx, 8);
1000     }
1001
1002     data = EVP_PKEY_CTX_get_data(ctx);
1003     if (!data) {
1004         GOSTerr(GOST_F_PKEY_GOST_GRASSHOPPER_MAC_SIGNCTX_INIT, GOST_R_MAC_KEY_NOT_SET);
1005         return 0;
1006     }
1007
1008     return 1;
1009 }
1010
1011 static int pkey_gost_mac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig,
1012                                  size_t *siglen, EVP_MD_CTX *mctx)
1013 {
1014     unsigned int tmpsiglen;
1015     int ret;
1016     struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
1017
1018     if (!siglen)
1019         return 0;
1020     tmpsiglen = *siglen;        /* for platforms where sizeof(int) !=
1021                                  * sizeof(size_t) */
1022
1023     if (!sig) {
1024         *siglen = data->mac_size;
1025         return 1;
1026     }
1027
1028     EVP_MD_meth_get_ctrl(EVP_MD_CTX_md(mctx))
1029         (mctx, EVP_MD_CTRL_XOF_LEN, data->mac_size, NULL);
1030     ret = EVP_DigestFinal_ex(mctx, sig, &tmpsiglen);
1031     *siglen = data->mac_size;
1032     return ret;
1033 }
1034
1035 /* ----------- misc callbacks -------------------------------------*/
1036
1037 /* Callback for both EVP_PKEY_check() and EVP_PKEY_public_check. */
1038 static int pkey_gost_check(EVP_PKEY *pkey)
1039 {
1040     return EC_KEY_check_key(EVP_PKEY_get0(pkey));
1041 }
1042
1043 /* ----------------------------------------------------------------*/
1044 int register_pmeth_gost(int id, EVP_PKEY_METHOD **pmeth, int flags)
1045 {
1046     *pmeth = EVP_PKEY_meth_new(id, flags);
1047     if (!*pmeth)
1048         return 0;
1049
1050     switch (id) {
1051     case NID_id_GostR3410_2001:
1052         EVP_PKEY_meth_set_ctrl(*pmeth,
1053                                pkey_gost_ctrl, pkey_gost_ec_ctrl_str_256);
1054         EVP_PKEY_meth_set_sign(*pmeth, NULL, pkey_gost_ec_cp_sign);
1055         EVP_PKEY_meth_set_verify(*pmeth, NULL, pkey_gost_ec_cp_verify);
1056
1057         EVP_PKEY_meth_set_keygen(*pmeth, NULL, pkey_gost2001cp_keygen);
1058
1059         EVP_PKEY_meth_set_encrypt(*pmeth,
1060                                   pkey_gost_encrypt_init,
1061                                   pkey_gost_encrypt);
1062         EVP_PKEY_meth_set_decrypt(*pmeth, NULL, pkey_gost_decrypt);
1063         EVP_PKEY_meth_set_derive(*pmeth,
1064                                  pkey_gost_derive_init, pkey_gost_ec_derive);
1065         EVP_PKEY_meth_set_paramgen(*pmeth, pkey_gost_paramgen_init,
1066                                    pkey_gost2001_paramgen);
1067     EVP_PKEY_meth_set_check(*pmeth, pkey_gost_check);
1068     EVP_PKEY_meth_set_public_check(*pmeth, pkey_gost_check);
1069         break;
1070     case NID_id_GostR3410_2012_256:
1071         EVP_PKEY_meth_set_ctrl(*pmeth,
1072                                pkey_gost_ctrl, pkey_gost_ec_ctrl_str_256);
1073         EVP_PKEY_meth_set_sign(*pmeth, NULL, pkey_gost_ec_cp_sign);
1074         EVP_PKEY_meth_set_verify(*pmeth, NULL, pkey_gost_ec_cp_verify);
1075
1076         EVP_PKEY_meth_set_keygen(*pmeth, NULL, pkey_gost2012cp_keygen);
1077
1078         EVP_PKEY_meth_set_encrypt(*pmeth,
1079                                   pkey_gost_encrypt_init,
1080                                   pkey_gost_encrypt);
1081         EVP_PKEY_meth_set_decrypt(*pmeth, NULL, pkey_gost_decrypt);
1082         EVP_PKEY_meth_set_derive(*pmeth,
1083                                  pkey_gost_derive_init, pkey_gost_ec_derive);
1084         EVP_PKEY_meth_set_paramgen(*pmeth,
1085                                    pkey_gost_paramgen_init,
1086                                    pkey_gost2012_paramgen);
1087     EVP_PKEY_meth_set_check(*pmeth, pkey_gost_check);
1088     EVP_PKEY_meth_set_public_check(*pmeth, pkey_gost_check);
1089         break;
1090     case NID_id_GostR3410_2012_512:
1091         EVP_PKEY_meth_set_ctrl(*pmeth,
1092                                pkey_gost_ctrl, pkey_gost_ec_ctrl_str_512);
1093         EVP_PKEY_meth_set_sign(*pmeth, NULL, pkey_gost_ec_cp_sign);
1094         EVP_PKEY_meth_set_verify(*pmeth, NULL, pkey_gost_ec_cp_verify);
1095
1096         EVP_PKEY_meth_set_keygen(*pmeth, NULL, pkey_gost2012cp_keygen);
1097
1098         EVP_PKEY_meth_set_encrypt(*pmeth,
1099                                   pkey_gost_encrypt_init,
1100                                   pkey_gost_encrypt);
1101         EVP_PKEY_meth_set_decrypt(*pmeth, NULL, pkey_gost_decrypt);
1102         EVP_PKEY_meth_set_derive(*pmeth,
1103                                  pkey_gost_derive_init, pkey_gost_ec_derive);
1104         EVP_PKEY_meth_set_paramgen(*pmeth,
1105                                    pkey_gost_paramgen_init,
1106                                    pkey_gost2012_paramgen);
1107     EVP_PKEY_meth_set_check(*pmeth, pkey_gost_check);
1108     EVP_PKEY_meth_set_public_check(*pmeth, pkey_gost_check);
1109         break;
1110     case NID_id_Gost28147_89_MAC:
1111         EVP_PKEY_meth_set_ctrl(*pmeth, pkey_gost_mac_ctrl,
1112                                pkey_gost_mac_ctrl_str);
1113         EVP_PKEY_meth_set_signctx(*pmeth, pkey_gost_mac_signctx_init,
1114                                   pkey_gost_mac_signctx);
1115         EVP_PKEY_meth_set_keygen(*pmeth, NULL, pkey_gost_mac_keygen);
1116         EVP_PKEY_meth_set_init(*pmeth, pkey_gost_mac_init);
1117         EVP_PKEY_meth_set_cleanup(*pmeth, pkey_gost_mac_cleanup);
1118         EVP_PKEY_meth_set_copy(*pmeth, pkey_gost_mac_copy);
1119         return 1;
1120     case NID_gost_mac_12:
1121         EVP_PKEY_meth_set_ctrl(*pmeth, pkey_gost_mac_ctrl,
1122                                pkey_gost_mac_ctrl_str);
1123         EVP_PKEY_meth_set_signctx(*pmeth, pkey_gost_mac_signctx_init,
1124                                   pkey_gost_mac_signctx);
1125         EVP_PKEY_meth_set_keygen(*pmeth, NULL, pkey_gost_mac_keygen_12);
1126         EVP_PKEY_meth_set_init(*pmeth, pkey_gost_mac_init);
1127         EVP_PKEY_meth_set_cleanup(*pmeth, pkey_gost_mac_cleanup);
1128         EVP_PKEY_meth_set_copy(*pmeth, pkey_gost_mac_copy);
1129         return 1;
1130     case NID_magma_mac:
1131         EVP_PKEY_meth_set_ctrl(*pmeth, pkey_gost_magma_mac_ctrl,
1132                                pkey_gost_magma_mac_ctrl_str);
1133         EVP_PKEY_meth_set_signctx(*pmeth, pkey_gost_magma_mac_signctx_init,
1134                                   pkey_gost_mac_signctx);
1135         EVP_PKEY_meth_set_keygen(*pmeth, NULL, pkey_gost_magma_mac_keygen);
1136         EVP_PKEY_meth_set_init(*pmeth, pkey_gost_magma_mac_init);
1137         EVP_PKEY_meth_set_cleanup(*pmeth, pkey_gost_mac_cleanup);
1138         EVP_PKEY_meth_set_copy(*pmeth, pkey_gost_mac_copy);
1139         return 1;
1140     case NID_grasshopper_mac:
1141     case NID_id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm_omac: /* FIXME beldmit */
1142         EVP_PKEY_meth_set_ctrl(*pmeth, pkey_gost_grasshopper_mac_ctrl,
1143                                pkey_gost_grasshopper_mac_ctrl_str);
1144         EVP_PKEY_meth_set_signctx(*pmeth, pkey_gost_grasshopper_mac_signctx_init,
1145                                   pkey_gost_mac_signctx);
1146         EVP_PKEY_meth_set_keygen(*pmeth, NULL, pkey_gost_grasshopper_mac_keygen);
1147         EVP_PKEY_meth_set_init(*pmeth, pkey_gost_grasshopper_mac_init);
1148         EVP_PKEY_meth_set_cleanup(*pmeth, pkey_gost_mac_cleanup);
1149         EVP_PKEY_meth_set_copy(*pmeth, pkey_gost_mac_copy);
1150         return 1;
1151     default:                   /* Unsupported method */
1152         return 0;
1153     }
1154     EVP_PKEY_meth_set_init(*pmeth, pkey_gost_init);
1155     EVP_PKEY_meth_set_cleanup(*pmeth, pkey_gost_cleanup);
1156
1157     EVP_PKEY_meth_set_copy(*pmeth, pkey_gost_copy);
1158     /*
1159      * FIXME derive etc...
1160      */
1161
1162     return 1;
1163 }