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