Submitted by: "Victor B. Wagner" <vitus@cryptocom.ru>
[openssl.git] / engines / ccgost / gost_pmeth.c
1 /**********************************************************************
2  *                          gost_pmeth.c                              *
3  *             Copyright (c) 2005-2006 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 0.9.9 for compilation                    *
9  **********************************************************************/
10 #include <openssl/evp.h>
11 #include <openssl/objects.h>
12 #include <openssl/ec.h>
13 #include <openssl/x509v3.h> /*For string_to_hex */
14 #include <stdlib.h>
15 #include <string.h>
16 #include <ctype.h>
17 #include "gost_params.h"
18 #include "gost_lcl.h"
19 #include "e_gost_err.h"
20 /*-------init, cleanup, copy - uniform for all algs  ---------------*/
21 /* Allocates new gost_pmeth_data structure and assigns it as data */
22 static int pkey_gost_init(EVP_PKEY_CTX *ctx)
23         {
24         struct gost_pmeth_data *data;
25         EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx);
26         data = OPENSSL_malloc(sizeof(struct gost_pmeth_data));
27         if (!data) return 0;
28         memset(data,0,sizeof(struct gost_pmeth_data));
29         if (pkey && EVP_PKEY_get0(pkey)) 
30                 {
31                 switch (EVP_PKEY_base_id(pkey)) {
32                 case NID_id_GostR3410_94:
33                   data->sign_param_nid = gost94_nid_by_params(EVP_PKEY_get0(pkey));
34                   break;
35                 case NID_id_GostR3410_2001:
36                    data->sign_param_nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(EVP_PKEY_get0((EVP_PKEY *)pkey)));
37                 break;
38                 default:
39                         return 0;
40                 }         
41                 }
42         EVP_PKEY_CTX_set_data(ctx,data);
43         return 1;
44         }
45
46 /* Copies contents of gost_pmeth_data structure */
47 static int pkey_gost_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
48         {
49         struct gost_pmeth_data *dst_data,*src_data;
50         if (!pkey_gost_init(dst))
51                 {
52                 return 0;
53                 }
54         src_data = EVP_PKEY_CTX_get_data(src);
55         dst_data = EVP_PKEY_CTX_get_data(dst);
56         *dst_data = *src_data;
57         if (src_data -> shared_ukm) {
58                 dst_data->shared_ukm=NULL;
59         }       
60         return 1;
61         }
62
63 /* Frees up gost_pmeth_data structure */
64 static void pkey_gost_cleanup (EVP_PKEY_CTX *ctx)
65         {
66         struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
67         if (data->shared_ukm) OPENSSL_free(data->shared_ukm);
68         OPENSSL_free(data);
69         }       
70
71 /* --------------------- control functions  ------------------------------*/
72 static int pkey_gost_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
73         {
74         struct gost_pmeth_data *pctx = (struct gost_pmeth_data*)EVP_PKEY_CTX_get_data(ctx);
75         switch (type)
76                 {
77                 case EVP_PKEY_CTRL_MD:
78                 {
79                 if (EVP_MD_type((const EVP_MD *)p2) != NID_id_GostR3411_94)
80                         {
81                         GOSTerr(GOST_F_PKEY_GOST_CTRL, GOST_R_INVALID_DIGEST_TYPE);
82                         return 0;
83                         }
84                 pctx->md = (EVP_MD *)p2;
85                 return 1;
86                 }
87                 break;
88
89                 case EVP_PKEY_CTRL_PKCS7_ENCRYPT:
90                 case EVP_PKEY_CTRL_PKCS7_DECRYPT:
91                 case EVP_PKEY_CTRL_PKCS7_SIGN:
92                         return 1;
93
94                 case EVP_PKEY_CTRL_GOST_PARAMSET:
95                         pctx->sign_param_nid = (int)p1;
96                         return 1;
97                 case EVP_PKEY_CTRL_SET_IV:
98                         pctx->shared_ukm=OPENSSL_malloc((int)p1);
99                         memcpy(pctx->shared_ukm,p2,(int) p1);
100                         return 1;
101                         
102                 }
103         return -2;
104         }
105
106
107 static int pkey_gost_ctrl94_str(EVP_PKEY_CTX *ctx,
108         const char *type, const char *value)
109         {
110         int param_nid=0;
111         if(!strcmp(type, param_ctrl_string))
112                 {
113                 if (!value)
114                         {
115                         return 0;
116                         }
117                 if (strlen(value) == 1)
118                         {
119                         switch(toupper(value[0]))
120                                 {
121                                 case 'A':
122                                         param_nid = NID_id_GostR3410_94_CryptoPro_A_ParamSet;
123                                         break;
124                                 case 'B':
125                                         param_nid = NID_id_GostR3410_94_CryptoPro_B_ParamSet;
126                                         break;
127                                 case 'C':
128                                         param_nid = NID_id_GostR3410_94_CryptoPro_C_ParamSet;
129                                         break;
130                                 case 'D':
131                                         param_nid = NID_id_GostR3410_94_CryptoPro_D_ParamSet;
132                                         break;
133                                 default:
134                                         return 0;
135                                         break;
136                                 }
137                         }
138                 else if ((strlen(value) == 2) && (toupper(value[0]) == 'X'))
139                         {
140                         switch (toupper(value[1]))
141                                 {
142                                 case 'A':
143                                         param_nid = NID_id_GostR3410_94_CryptoPro_XchA_ParamSet;
144                                         break;
145                                 case 'B':
146                                         param_nid = NID_id_GostR3410_94_CryptoPro_XchB_ParamSet;
147                                         break;
148                                 case 'C':
149                                         param_nid = NID_id_GostR3410_94_CryptoPro_XchC_ParamSet;
150                                         break;
151                                 default:
152                                         return 0;
153                                         break;
154                                 }
155                         }
156                 else
157                         {
158                         R3410_params *p = R3410_paramset;
159                         param_nid = OBJ_txt2nid(value);
160                         if (param_nid == NID_undef)
161                                 {
162                                 return 0;
163                                 }
164                         for (;p->nid != NID_undef;p++)
165                                 {
166                                 if (p->nid == param_nid) break;
167                                 }
168                         if (p->nid == NID_undef)
169                                 {
170                                 GOSTerr(GOST_F_PKEY_GOST_CTRL94_STR,
171                                         GOST_R_INVALID_PARAMSET);
172                                 return 0;
173                                 }
174                         }
175
176                 return pkey_gost_ctrl(ctx, EVP_PKEY_CTRL_GOST_PARAMSET,
177                         param_nid, NULL);
178                 }
179         return -2;
180         }
181
182 static int pkey_gost_ctrl01_str(EVP_PKEY_CTX *ctx,
183         const char *type, const char *value)
184         {
185         int param_nid=0;
186         if(!strcmp(type, param_ctrl_string))
187                 {
188                 if (!value)
189                         {
190                         return 0;
191                         }
192                 if (strlen(value) == 1)
193                         {
194                         switch(toupper(value[0]))
195                                 {
196                                 case 'A':
197                                         param_nid = NID_id_GostR3410_2001_CryptoPro_A_ParamSet;
198                                         break;  
199                                 case 'B':
200                                         param_nid = NID_id_GostR3410_2001_CryptoPro_B_ParamSet;
201                                         break;
202                                 case 'C':
203                                         param_nid = NID_id_GostR3410_2001_CryptoPro_C_ParamSet;
204                                         break;
205                                 case '0':
206                                         param_nid = NID_id_GostR3410_2001_TestParamSet;
207                                         break;
208                                 default:
209                                         return 0;
210                                         break;
211                                 }
212                         }
213                 else if ((strlen(value) == 2) && (toupper(value[0]) == 'X'))
214                         {
215                         switch (toupper(value[1]))
216                                 {
217                                 case 'A':
218                                         param_nid = NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet;
219                                         break;
220                                 case 'B':
221                                         param_nid = NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet;
222                                         break;
223                                 default:
224                                         return 0;
225                                         break;
226                                 }
227                         }
228                 else
229                         {
230                         R3410_2001_params *p = R3410_2001_paramset;
231                         param_nid = OBJ_txt2nid(value);
232                         if (param_nid == NID_undef)
233                                 {
234                                 return 0;
235                                 }
236                         for (;p->nid != NID_undef;p++)
237                                 {
238                                 if (p->nid == param_nid) break;
239                                 }
240                         if (p->nid == NID_undef)
241                                 {
242                                 GOSTerr(GOST_F_PKEY_GOST_CTRL01_STR,
243                                         GOST_R_INVALID_PARAMSET);
244                                 return 0;
245                                 }
246                         }
247
248                 return pkey_gost_ctrl(ctx, EVP_PKEY_CTRL_GOST_PARAMSET,
249                         param_nid, NULL);
250                 }
251         return -2;
252         }
253
254 /* --------------------- key generation  --------------------------------*/
255
256 static int pkey_gost_paramgen_init(EVP_PKEY_CTX *ctx) {
257         return 1;
258 }       
259 static int pkey_gost94_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) 
260         {
261         struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
262         DSA *dsa=NULL;
263         if (data->sign_param_nid == NID_undef)
264                 {
265                         GOSTerr(GOST_F_PKEY_GOST94_PARAMGEN,
266                                 GOST_R_NO_PARAMETERS_SET);
267                         return 0;
268                 }
269         dsa = DSA_new();
270         if (!fill_GOST94_params(dsa,data->sign_param_nid))
271                 {
272                 DSA_free(dsa);
273                 return 0;
274                 }
275         EVP_PKEY_assign(pkey,NID_id_GostR3410_94,dsa);
276         return 1;
277         }
278 static int pkey_gost01_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
279         {
280         struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
281         EC_KEY *ec=NULL;
282
283         if (data->sign_param_nid == NID_undef)
284                 {
285                         GOSTerr(GOST_F_PKEY_GOST01_PARAMGEN,
286                                 GOST_R_NO_PARAMETERS_SET);
287                         return 0;
288                 }
289         if (!ec)        
290                 ec = EC_KEY_new();
291         if (!fill_GOST2001_params(ec,data->sign_param_nid))
292                 {
293                 EC_KEY_free(ec);
294                 return 0;
295                 }
296         EVP_PKEY_assign(pkey,NID_id_GostR3410_2001,ec);
297         return 1;
298         }
299
300 /* Generates Gost_R3410_94_cp key */
301 static int pkey_gost94cp_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
302         {
303         DSA *dsa;
304         if (!pkey_gost94_paramgen(ctx,pkey)) return 0;
305         dsa = EVP_PKEY_get0(pkey);
306         gost_sign_keygen(dsa);
307         return 1;
308         }
309
310 /* Generates GOST_R3410 2001 key and assigns it using specified type */
311 static int pkey_gost01cp_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
312         {
313         EC_KEY *ec;
314     if (!pkey_gost01_paramgen(ctx,pkey)) return 0;
315         ec = EVP_PKEY_get0(pkey);
316         gost2001_keygen(ec);
317         return 1;
318         }
319
320
321
322 /* ----------- sign callbacks --------------------------------------*/
323
324 static int pkey_gost94_cp_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
325         const unsigned char *tbs, size_t tbs_len)
326         {
327         DSA_SIG *unpacked_sig=NULL;
328         EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx);
329         if (!siglen) return 0;
330         if (!sig)
331                 {
332                 *siglen= 64; /* better to check size of pkey->pkey.dsa-q */
333                 return 1;
334                 }       
335         unpacked_sig = gost_do_sign(tbs,tbs_len,EVP_PKEY_get0(pkey));
336         if (!unpacked_sig)
337                 {
338                 return 0;
339                 }
340         return pack_sign_cp(unpacked_sig,32,sig,siglen);
341         }
342
343 static int pkey_gost01_cp_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
344         const unsigned char *tbs, size_t tbs_len)
345         {
346         DSA_SIG *unpacked_sig=NULL;
347         EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx);
348         if (!siglen) return 0;
349         if (!sig)
350                 {
351                 *siglen= 64; /* better to check size of curve order*/
352                 return 1;
353                 }       
354         unpacked_sig = gost2001_do_sign(tbs,tbs_len,EVP_PKEY_get0(pkey));
355         if (!unpacked_sig)
356                 {
357                 return 0;
358                 }
359         return pack_sign_cp(unpacked_sig,32,sig,siglen);
360         }
361
362 /* ------------------- verify callbacks ---------------------------*/
363
364 static int pkey_gost94_cp_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig,
365         size_t siglen, const unsigned char *tbs, size_t tbs_len)
366         {
367         int ok = 0;
368         EVP_PKEY* pub_key = EVP_PKEY_CTX_get0_pkey(ctx);
369         DSA_SIG *s=unpack_cp_signature(sig,siglen);
370         if (!s) return 0;
371         if (pub_key) ok = gost_do_verify(tbs,tbs_len,s,EVP_PKEY_get0(pub_key));
372         DSA_SIG_free(s);
373         return ok;
374         }
375
376
377 static int pkey_gost01_cp_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig,
378         size_t siglen, const unsigned char *tbs, size_t tbs_len)
379         {
380         int ok = 0;
381         EVP_PKEY* pub_key = EVP_PKEY_CTX_get0_pkey(ctx);
382         DSA_SIG *s=unpack_cp_signature(sig,siglen);
383         if (!s) return 0;
384 #ifdef DEBUG_SIGN       
385         fprintf(stderr,"R=");
386         BN_print_fp(stderr,s->r);
387         fprintf(stderr,"\nS=");
388         BN_print_fp(stderr,s->s);
389         fprintf(stderr,"\n");
390 #endif  
391         if (pub_key) ok = gost2001_do_verify(tbs,tbs_len,s,EVP_PKEY_get0(pub_key));
392         DSA_SIG_free(s);
393         return ok;
394         }
395
396 /* ------------- encrypt init -------------------------------------*/
397 /* Generates ephermeral key */
398 static int pkey_gost_encrypt_init(EVP_PKEY_CTX *ctx)
399         {
400         return 1;
401         }
402 /* --------------- Derive init ------------------------------------*/
403 static int pkey_gost_derive_init(EVP_PKEY_CTX *ctx)
404 {
405         return 1;
406 }
407 /* -------- PKEY_METHOD for GOST MAC algorithm --------------------*/
408 static int pkey_gost_mac_init(EVP_PKEY_CTX *ctx)
409         {
410         struct gost_mac_pmeth_data *data;
411         data = OPENSSL_malloc(sizeof(struct gost_mac_pmeth_data));
412         if (!data) return 0;
413         memset(data,0,sizeof(struct gost_mac_pmeth_data));
414         EVP_PKEY_CTX_set_data(ctx,data);
415         return 1;
416         }       
417 static void pkey_gost_mac_cleanup (EVP_PKEY_CTX *ctx)
418         {
419         struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
420         OPENSSL_free(data);
421         }       
422 static int pkey_gost_mac_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
423         {
424         struct gost_mac_pmeth_data *dst_data,*src_data;
425         if (!pkey_gost_mac_init(dst))
426                 {
427                 return 0;
428                 }
429         src_data = EVP_PKEY_CTX_get_data(src);
430         dst_data = EVP_PKEY_CTX_get_data(dst);
431         *dst_data = *src_data;
432         return 1;
433         }
434         
435 static int pkey_gost_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
436         {
437         struct gost_mac_pmeth_data *data =
438 (struct gost_mac_pmeth_data*)EVP_PKEY_CTX_get_data(ctx);
439
440         switch (type)
441                 {
442                 case EVP_PKEY_CTRL_MD:
443                 {
444                 if (EVP_MD_type((const EVP_MD *)p2) != NID_id_Gost28147_89_MAC)
445                         {
446                         GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL, GOST_R_INVALID_DIGEST_TYPE);
447                         return 0;
448                         }
449                 data->md = (EVP_MD *)p2;
450                 return 1;
451                 }
452                 break;
453
454                 case EVP_PKEY_CTRL_PKCS7_ENCRYPT:
455                 case EVP_PKEY_CTRL_PKCS7_DECRYPT:
456                 case EVP_PKEY_CTRL_PKCS7_SIGN:
457                         return 1;
458                 case EVP_PKEY_CTRL_SET_MAC_KEY:
459                         if (p1 != 32) 
460                                 {
461                                 GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL,
462                                         GOST_R_INVALID_MAC_KEY_LENGTH);
463                                 return 0;
464                                 }
465
466                         memcpy(data->key,p2,32);
467                         data->key_set = 1;
468                         return 1;
469                 case EVP_PKEY_CTRL_DIGESTINIT:
470                         { 
471                         EVP_MD_CTX *mctx = p2;
472                         void *key;
473                         if (!data->key_set)
474                                 { 
475                                 EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx);
476                                 if (!pkey) 
477                                         {
478                                         GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL,GOST_R_MAC_KEY_NOT_SET);
479                                         return 0;
480                                         }
481                                 key = EVP_PKEY_get0(pkey);
482                                 if (!key) 
483                                         {
484                                         GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL,GOST_R_MAC_KEY_NOT_SET);
485                                         return 0;
486                                         }
487                                 } else {
488                                 key = &(data->key);
489                                 }
490                         return mctx->digest->md_ctrl(mctx,EVP_MD_CTRL_SET_KEY,32,key);
491                         }  
492                 }       
493         return -2;
494         }
495 static int pkey_gost_mac_ctrl_str(EVP_PKEY_CTX *ctx,
496         const char *type, const char *value)
497         {
498         if (!strcmp(type, key_ctrl_string)) 
499                 {
500                 if (strlen(value)!=32) 
501                         {
502                         GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL_STR,
503                                 GOST_R_INVALID_MAC_KEY_LENGTH);
504                         return 0;       
505                         }
506                 return pkey_gost_mac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY,
507                         32,(char *)value);
508                 }
509         if (!strcmp(type, hexkey_ctrl_string)) 
510                 {
511                         long keylen; int ret;
512                         unsigned char *keybuf=string_to_hex(value,&keylen);
513                         if (keylen != 32) 
514                                 {
515                                 GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL_STR,
516                                         GOST_R_INVALID_MAC_KEY_LENGTH);
517                                 return 0;       
518                                 }
519                         ret= pkey_gost_mac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY,
520                                 32,keybuf);
521                         OPENSSL_free(keybuf);
522                         return ret;
523         
524                 }
525         return -2;
526         }       
527
528 static int pkey_gost_mac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
529         {
530                 struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
531                 unsigned char *keydata;
532                 if (!data->key_set) 
533                 {
534                         GOSTerr(GOST_F_PKEY_GOST_MAC_KEYGEN,GOST_R_MAC_KEY_NOT_SET);
535                         return 0;
536                 }
537                 keydata = OPENSSL_malloc(32);
538                 memcpy(keydata,data->key,32);
539                 EVP_PKEY_assign(pkey, NID_id_Gost28147_89_MAC, keydata);
540                 return 1;
541         }
542
543 static int pkey_gost_mac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
544         {
545         return 1;
546 }
547
548 static int pkey_gost_mac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, EVP_MD_CTX *mctx)
549         {
550                 unsigned int tmpsiglen=*siglen; /* for platforms where sizeof(int)!=sizeof(size_t)*/
551                 int ret;
552                 if (!sig) 
553                         {
554                         *siglen = 4;
555                         return 1;
556                         }
557                 ret=EVP_DigestFinal_ex(mctx,sig,&tmpsiglen);
558                 *siglen = tmpsiglen;
559                 return ret;
560         }
561 /* ----------------------------------------------------------------*/
562 int register_pmeth_gost(int id, EVP_PKEY_METHOD **pmeth,int flags)
563         {
564         *pmeth = EVP_PKEY_meth_new(id, flags);
565         if (!*pmeth) return 0;
566
567         switch (id)
568                 {
569                 case NID_id_GostR3410_94:
570                         EVP_PKEY_meth_set_ctrl(*pmeth,pkey_gost_ctrl, pkey_gost_ctrl94_str);
571                         EVP_PKEY_meth_set_keygen(*pmeth,NULL,pkey_gost94cp_keygen);
572                         EVP_PKEY_meth_set_sign(*pmeth, NULL, pkey_gost94_cp_sign);
573                         EVP_PKEY_meth_set_verify(*pmeth, NULL, pkey_gost94_cp_verify);
574                         EVP_PKEY_meth_set_encrypt(*pmeth,
575                                 pkey_gost_encrypt_init, pkey_GOST94cp_encrypt);
576                         EVP_PKEY_meth_set_decrypt(*pmeth, NULL, pkey_GOST94cp_decrypt);
577                         EVP_PKEY_meth_set_derive(*pmeth,
578                                 pkey_gost_derive_init, pkey_gost94_derive);
579                         EVP_PKEY_meth_set_paramgen(*pmeth, pkey_gost_paramgen_init,pkey_gost94_paramgen);       
580                         break;
581                 case NID_id_GostR3410_2001:
582                         EVP_PKEY_meth_set_ctrl(*pmeth,pkey_gost_ctrl, pkey_gost_ctrl01_str);
583                         EVP_PKEY_meth_set_sign(*pmeth, NULL, pkey_gost01_cp_sign);
584                         EVP_PKEY_meth_set_verify(*pmeth, NULL, pkey_gost01_cp_verify);
585
586                         EVP_PKEY_meth_set_keygen(*pmeth, NULL, pkey_gost01cp_keygen);
587
588                         EVP_PKEY_meth_set_encrypt(*pmeth,
589                                 pkey_gost_encrypt_init, pkey_GOST01cp_encrypt);
590                         EVP_PKEY_meth_set_decrypt(*pmeth, NULL, pkey_GOST01cp_decrypt);
591                         EVP_PKEY_meth_set_derive(*pmeth,
592                                 pkey_gost_derive_init, pkey_gost2001_derive);
593                         EVP_PKEY_meth_set_paramgen(*pmeth, pkey_gost_paramgen_init,pkey_gost01_paramgen);       
594                         break;
595                 case NID_id_Gost28147_89_MAC:
596                         EVP_PKEY_meth_set_ctrl(*pmeth,pkey_gost_mac_ctrl, pkey_gost_mac_ctrl_str);
597                         EVP_PKEY_meth_set_signctx(*pmeth,pkey_gost_mac_signctx_init, pkey_gost_mac_signctx);
598                         EVP_PKEY_meth_set_keygen(*pmeth,NULL, pkey_gost_mac_keygen);
599                         EVP_PKEY_meth_set_init(*pmeth,pkey_gost_mac_init);
600                         EVP_PKEY_meth_set_cleanup(*pmeth,pkey_gost_mac_cleanup);
601                         EVP_PKEY_meth_set_copy(*pmeth,pkey_gost_mac_copy);
602                         return 1;
603                 default: /*Unsupported method*/
604                         return 0;
605                 }
606         EVP_PKEY_meth_set_init(*pmeth, pkey_gost_init);
607         EVP_PKEY_meth_set_cleanup(*pmeth, pkey_gost_cleanup);
608
609         EVP_PKEY_meth_set_copy(*pmeth, pkey_gost_copy);
610         /*FIXME derive etc...*/
611         
612         return 1;
613         }
614