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