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