gost_pmeth.c 15.9 KB
Newer Older
1
/**********************************************************************
2
 *                          gost_pmeth.c                              *
3 4 5 6 7 8 9 10 11 12
 *             Copyright (c) 2005-2006 Cryptocom LTD                  *
 *         This file is distributed under the same license as OpenSSL *
 *                                                                    *
 *   Implementation of RFC 4357 (GOST R 34.10) Publick key method     *
 *       for OpenSSL                                                  *
 *          Requires OpenSSL 0.9.9 for compilation                    *
 **********************************************************************/
#include <openssl/evp.h>
#include <openssl/objects.h>
#include <openssl/ec.h>
13
#include <openssl/x509v3.h> /*For string_to_hex */
14 15 16
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
17 18
#include "gost_params.h"
#include "gost_lcl.h"
19 20 21
#include "e_gost_err.h"
/*-------init, cleanup, copy - uniform for all algs  ---------------*/
/* Allocates new gost_pmeth_data structure and assigns it as data */
22 23
static int pkey_gost_init(EVP_PKEY_CTX *ctx)
	{
24
	struct gost_pmeth_data *data;
25
	EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx);
26 27 28
	data = OPENSSL_malloc(sizeof(struct gost_pmeth_data));
	if (!data) return 0;
	memset(data,0,sizeof(struct gost_pmeth_data));
29 30 31 32 33 34 35 36 37 38 39 40 41
	if (pkey && EVP_PKEY_get0(pkey)) 
		{
		switch (EVP_PKEY_base_id(pkey)) {
		case NID_id_GostR3410_94:
		  data->sign_param_nid = gost94_nid_by_params(EVP_PKEY_get0(pkey));
		  break;
		case NID_id_GostR3410_2001:
		   data->sign_param_nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(EVP_PKEY_get0((EVP_PKEY *)pkey)));
		break;
		default:
			return 0;
		}	  
		}
42 43
	EVP_PKEY_CTX_set_data(ctx,data);
	return 1;
44 45
	}

46 47
/* Copies contents of gost_pmeth_data structure */
static int pkey_gost_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
48
	{
49
	struct gost_pmeth_data *dst_data,*src_data;
50 51
	if (!pkey_gost_init(dst))
		{
52
		return 0;
53
		}
54 55 56
	src_data = EVP_PKEY_CTX_get_data(src);
	dst_data = EVP_PKEY_CTX_get_data(dst);
	*dst_data = *src_data;
57 58 59
	if (src_data -> shared_ukm) {
		dst_data->shared_ukm=NULL;
	}	
60
	return 1;
61 62
	}

63
/* Frees up gost_pmeth_data structure */
64 65
static void pkey_gost_cleanup (EVP_PKEY_CTX *ctx)
	{
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 75
	struct gost_pmeth_data *pctx = (struct gost_pmeth_data*)EVP_PKEY_CTX_get_data(ctx);
	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 82
			GOSTerr(GOST_F_PKEY_GOST_CTRL, GOST_R_INVALID_DIGEST_TYPE);
			return 0;
83
			}
84 85 86 87
		pctx->md = (EVP_MD *)p2;
		return 1;
		}
		break;
88 89 90 91

		case EVP_PKEY_CTRL_PKCS7_ENCRYPT:
		case EVP_PKEY_CTRL_PKCS7_DECRYPT:
		case EVP_PKEY_CTRL_PKCS7_SIGN:
92
			return 1;
93 94 95 96

		case EVP_PKEY_CTRL_GOST_PARAMSET:
			pctx->sign_param_nid = (int)p1;
			return 1;
97 98 99 100
		case EVP_PKEY_CTRL_SET_IV:
			pctx->shared_ukm=OPENSSL_malloc((int)p1);
			memcpy(pctx->shared_ukm,p2,(int) p1);
			return 1;
101 102 103 104 105 106 107 108
		case EVP_PKEY_CTRL_PEER_KEY:
			if (p1 == 0 || p1 == 1) /* call from EVP_PKEY_derive_set_peer */
				return 1;
			if (p1 == 2)		/* TLS: peer key used? */
				return pctx->peer_key_used;
			if (p1 == 3)		/* TLS: peer key used! */
				return (pctx->peer_key_used = 1);
			return -2;
109
		}
110
	return -2;
111
	}
112

113 114 115 116

static int pkey_gost_ctrl94_str(EVP_PKEY_CTX *ctx,
	const char *type, const char *value)
	{
117
	int param_nid=0;
118 119 120 121
	if(!strcmp(type, param_ctrl_string))
		{
		if (!value)
			{
122
			return 0;
123 124 125
			}
		if (strlen(value) == 1)
			{
126
			switch(toupper((unsigned char)value[0]))
127
				{
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
				case 'A':
					param_nid = NID_id_GostR3410_94_CryptoPro_A_ParamSet;
					break;
				case 'B':
					param_nid = NID_id_GostR3410_94_CryptoPro_B_ParamSet;
					break;
				case 'C':
					param_nid = NID_id_GostR3410_94_CryptoPro_C_ParamSet;
					break;
				case 'D':
					param_nid = NID_id_GostR3410_94_CryptoPro_D_ParamSet;
					break;
				default:
					return 0;
					break;
143
				}
144
			}
145
		else if ((strlen(value) == 2) && (toupper((unsigned char)value[0]) == 'X'))
146
			{
147
			switch (toupper((unsigned char)value[1]))
148
				{
149 150 151 152 153 154 155 156 157 158 159 160
				case 'A':
					param_nid = NID_id_GostR3410_94_CryptoPro_XchA_ParamSet;
					break;
				case 'B':
					param_nid = NID_id_GostR3410_94_CryptoPro_XchB_ParamSet;
					break;
				case 'C':
					param_nid = NID_id_GostR3410_94_CryptoPro_XchC_ParamSet;
					break;
				default:
					return 0;
					break;
161
				}
162
			}
163 164
		else
			{
165 166
			R3410_params *p = R3410_paramset;
			param_nid = OBJ_txt2nid(value);
167 168
			if (param_nid == NID_undef)
				{
169
				return 0;
170 171 172
				}
			for (;p->nid != NID_undef;p++)
				{
173
				if (p->nid == param_nid) break;
174 175 176
				}
			if (p->nid == NID_undef)
				{
177
				GOSTerr(GOST_F_PKEY_GOST_CTRL94_STR,
178
					GOST_R_INVALID_PARAMSET);
179
				return 0;
180
				}
181 182
			}

183 184 185
		return pkey_gost_ctrl(ctx, EVP_PKEY_CTRL_GOST_PARAMSET,
			param_nid, NULL);
		}
186
	return -2;
187
	}
188

189 190 191
static int pkey_gost_ctrl01_str(EVP_PKEY_CTX *ctx,
	const char *type, const char *value)
	{
192
	int param_nid=0;
193 194 195 196
	if(!strcmp(type, param_ctrl_string))
		{
		if (!value)
			{
197
			return 0;
198 199 200
			}
		if (strlen(value) == 1)
			{
201
			switch(toupper((unsigned char)value[0]))
202
				{
203 204 205 206 207 208 209 210 211 212 213 214 215 216 217
				case 'A':
					param_nid = NID_id_GostR3410_2001_CryptoPro_A_ParamSet;
					break;	
				case 'B':
					param_nid = NID_id_GostR3410_2001_CryptoPro_B_ParamSet;
					break;
				case 'C':
					param_nid = NID_id_GostR3410_2001_CryptoPro_C_ParamSet;
					break;
				case '0':
					param_nid = NID_id_GostR3410_2001_TestParamSet;
					break;
				default:
					return 0;
					break;
218
				}
219
			}
220
		else if ((strlen(value) == 2) && (toupper((unsigned char)value[0]) == 'X'))
221
			{
222
			switch (toupper((unsigned char)value[1]))
223
				{
224 225 226 227 228 229 230 231 232
				case 'A':
					param_nid = NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet;
					break;
				case 'B':
					param_nid = NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet;
					break;
				default:
					return 0;
					break;
233
				}
234
			}
235 236
		else
			{
237 238
			R3410_2001_params *p = R3410_2001_paramset;
			param_nid = OBJ_txt2nid(value);
239 240
			if (param_nid == NID_undef)
				{
241
				return 0;
242 243 244
				}
			for (;p->nid != NID_undef;p++)
				{
245
				if (p->nid == param_nid) break;
246 247 248
				}
			if (p->nid == NID_undef)
				{
249
				GOSTerr(GOST_F_PKEY_GOST_CTRL01_STR,
250
					GOST_R_INVALID_PARAMSET);
251
				return 0;
252
				}
253 254
			}

255 256 257
		return pkey_gost_ctrl(ctx, EVP_PKEY_CTRL_GOST_PARAMSET,
			param_nid, NULL);
		}
258
	return -2;
259 260
	}

261
/* --------------------- key generation  --------------------------------*/
262

263 264 265 266
static int pkey_gost_paramgen_init(EVP_PKEY_CTX *ctx) {
	return 1;
}	
static int pkey_gost94_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) 
267
	{
268 269
	struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
	DSA *dsa=NULL;
270 271
	if (data->sign_param_nid == NID_undef)
		{
272
			GOSTerr(GOST_F_PKEY_GOST94_PARAMGEN,
273
				GOST_R_NO_PARAMETERS_SET);
274
			return 0;
275
		}
276
	dsa = DSA_new();
277 278
	if (!fill_GOST94_params(dsa,data->sign_param_nid))
		{
279 280
		DSA_free(dsa);
		return 0;
281
		}
282
	EVP_PKEY_assign(pkey,NID_id_GostR3410_94,dsa);
283
	return 1;
284
	}
285
static int pkey_gost01_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
286
	{
287 288
	struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
	EC_KEY *ec=NULL;
289

290 291
	if (data->sign_param_nid == NID_undef)
		{
292
			GOSTerr(GOST_F_PKEY_GOST01_PARAMGEN,
293
				GOST_R_NO_PARAMETERS_SET);
294 295
			return 0;
		}
296 297
	if (!ec) 	
		ec = EC_KEY_new();
298 299
	if (!fill_GOST2001_params(ec,data->sign_param_nid))
		{
300 301
		EC_KEY_free(ec);
		return 0;
302
		}
303
	EVP_PKEY_assign(pkey,NID_id_GostR3410_2001,ec);
304
	return 1;
305 306
	}

307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326
/* Generates Gost_R3410_94_cp key */
static int pkey_gost94cp_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
	{
	DSA *dsa;
	if (!pkey_gost94_paramgen(ctx,pkey)) return 0;
	dsa = EVP_PKEY_get0(pkey);
	gost_sign_keygen(dsa);
	return 1;
	}

/* Generates GOST_R3410 2001 key and assigns it using specified type */
static int pkey_gost01cp_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
	{
	EC_KEY *ec;
    if (!pkey_gost01_paramgen(ctx,pkey)) return 0;
	ec = EVP_PKEY_get0(pkey);
	gost2001_keygen(ec);
	return 1;
	}

327

328

329 330 331 332
/* ----------- sign callbacks --------------------------------------*/

static int pkey_gost94_cp_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
	const unsigned char *tbs, size_t tbs_len)
333
	{
334 335 336
	DSA_SIG *unpacked_sig=NULL;
	EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx);
	if (!siglen) return 0;
337 338
	if (!sig)
		{
339 340
		*siglen= 64; /* better to check size of pkey->pkey.dsa-q */
		return 1;
341
		}	
342
	unpacked_sig = gost_do_sign(tbs,tbs_len,EVP_PKEY_get0(pkey));
343 344
	if (!unpacked_sig)
		{
345
		return 0;
346
		}
347
	return pack_sign_cp(unpacked_sig,32,sig,siglen);
348 349
	}

350 351
static int pkey_gost01_cp_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
	const unsigned char *tbs, size_t tbs_len)
352
	{
353 354 355
	DSA_SIG *unpacked_sig=NULL;
	EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx);
	if (!siglen) return 0;
356 357
	if (!sig)
		{
358 359
		*siglen= 64; /* better to check size of curve order*/
		return 1;
360
		}	
361
	unpacked_sig = gost2001_do_sign(tbs,tbs_len,EVP_PKEY_get0(pkey));
362 363
	if (!unpacked_sig)
		{
364
		return 0;
365
		}
366
	return pack_sign_cp(unpacked_sig,32,sig,siglen);
367 368
	}

369 370 371 372
/* ------------------- verify callbacks ---------------------------*/

static int pkey_gost94_cp_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig,
	size_t siglen, const unsigned char *tbs, size_t tbs_len)
373
	{
374 375 376 377 378 379 380
	int ok = 0;
	EVP_PKEY* pub_key = EVP_PKEY_CTX_get0_pkey(ctx);
	DSA_SIG *s=unpack_cp_signature(sig,siglen);
	if (!s) return 0;
	if (pub_key) ok = gost_do_verify(tbs,tbs_len,s,EVP_PKEY_get0(pub_key));
	DSA_SIG_free(s);
	return ok;
381 382
	}

383 384 385

static int pkey_gost01_cp_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig,
	size_t siglen, const unsigned char *tbs, size_t tbs_len)
386
	{
387 388 389 390
	int ok = 0;
	EVP_PKEY* pub_key = EVP_PKEY_CTX_get0_pkey(ctx);
	DSA_SIG *s=unpack_cp_signature(sig,siglen);
	if (!s) return 0;
391
#ifdef DEBUG_SIGN	
392 393 394 395 396
	fprintf(stderr,"R=");
	BN_print_fp(stderr,s->r);
	fprintf(stderr,"\nS=");
	BN_print_fp(stderr,s->s);
	fprintf(stderr,"\n");
397
#endif	
398 399 400
	if (pub_key) ok = gost2001_do_verify(tbs,tbs_len,s,EVP_PKEY_get0(pub_key));
	DSA_SIG_free(s);
	return ok;
401 402
	}

403 404
/* ------------- encrypt init -------------------------------------*/
/* Generates ephermeral key */
405 406
static int pkey_gost_encrypt_init(EVP_PKEY_CTX *ctx)
	{
407
	return 1;
408
	}
409
/* --------------- Derive init ------------------------------------*/
B
Ben Laurie 已提交
410
static int pkey_gost_derive_init(EVP_PKEY_CTX *ctx)
411 412 413
{
	return 1;
}
414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441
/* -------- PKEY_METHOD for GOST MAC algorithm --------------------*/
static int pkey_gost_mac_init(EVP_PKEY_CTX *ctx)
	{
	struct gost_mac_pmeth_data *data;
	data = OPENSSL_malloc(sizeof(struct gost_mac_pmeth_data));
	if (!data) return 0;
	memset(data,0,sizeof(struct gost_mac_pmeth_data));
	EVP_PKEY_CTX_set_data(ctx,data);
	return 1;
	}	
static void pkey_gost_mac_cleanup (EVP_PKEY_CTX *ctx)
	{
	struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
	OPENSSL_free(data);
	}	
static int pkey_gost_mac_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
	{
	struct gost_mac_pmeth_data *dst_data,*src_data;
	if (!pkey_gost_mac_init(dst))
		{
		return 0;
		}
	src_data = EVP_PKEY_CTX_get_data(src);
	dst_data = EVP_PKEY_CTX_get_data(dst);
	*dst_data = *src_data;
	return 1;
	}
	
442
static int pkey_gost_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
443 444 445
	{
	struct gost_mac_pmeth_data *data =
(struct gost_mac_pmeth_data*)EVP_PKEY_CTX_get_data(ctx);
446

447 448 449 450
	switch (type)
		{
		case EVP_PKEY_CTRL_MD:
		{
451
		if (EVP_MD_type((const EVP_MD *)p2) != NID_id_Gost28147_89_MAC)
452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496
			{
			GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL, GOST_R_INVALID_DIGEST_TYPE);
			return 0;
			}
		data->md = (EVP_MD *)p2;
		return 1;
		}
		break;

		case EVP_PKEY_CTRL_PKCS7_ENCRYPT:
		case EVP_PKEY_CTRL_PKCS7_DECRYPT:
		case EVP_PKEY_CTRL_PKCS7_SIGN:
			return 1;
		case EVP_PKEY_CTRL_SET_MAC_KEY:
			if (p1 != 32) 
				{
				GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL,
					GOST_R_INVALID_MAC_KEY_LENGTH);
				return 0;
				}

			memcpy(data->key,p2,32);
			data->key_set = 1;
			return 1;
		case EVP_PKEY_CTRL_DIGESTINIT:
			{ 
			EVP_MD_CTX *mctx = p2;
			void *key;
			if (!data->key_set)
				{ 
				EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx);
				if (!pkey) 
					{
					GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL,GOST_R_MAC_KEY_NOT_SET);
					return 0;
					}
				key = EVP_PKEY_get0(pkey);
				if (!key) 
					{
					GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL,GOST_R_MAC_KEY_NOT_SET);
					return 0;
					}
				} else {
				key = &(data->key);
				}
497
			return mctx->digest->md_ctrl(mctx,EVP_MD_CTRL_SET_KEY,32,key);
498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523
			}  
		}	
	return -2;
	}
static int pkey_gost_mac_ctrl_str(EVP_PKEY_CTX *ctx,
	const char *type, const char *value)
	{
	if (!strcmp(type, key_ctrl_string)) 
		{
		if (strlen(value)!=32) 
			{
			GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL_STR,
				GOST_R_INVALID_MAC_KEY_LENGTH);
			return 0;	
			}
		return pkey_gost_mac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY,
			32,(char *)value);
		}
	if (!strcmp(type, hexkey_ctrl_string)) 
		{
			long keylen; int ret;
			unsigned char *keybuf=string_to_hex(value,&keylen);
			if (keylen != 32) 
				{
				GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL_STR,
					GOST_R_INVALID_MAC_KEY_LENGTH);
D
Dr. Stephen Henson 已提交
524
				OPENSSL_free(keybuf);
525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552
				return 0;	
				}
			ret= pkey_gost_mac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY,
				32,keybuf);
			OPENSSL_free(keybuf);
			return ret;
	
		}
	return -2;
	}	

static int pkey_gost_mac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
	{
		struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
		unsigned char *keydata;
		if (!data->key_set) 
		{
			GOSTerr(GOST_F_PKEY_GOST_MAC_KEYGEN,GOST_R_MAC_KEY_NOT_SET);
			return 0;
		}
		keydata = OPENSSL_malloc(32);
		memcpy(keydata,data->key,32);
		EVP_PKEY_assign(pkey, NID_id_Gost28147_89_MAC, keydata);
		return 1;
	}

static int pkey_gost_mac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
	{
D
Dr. Stephen Henson 已提交
553
	return 1;
554 555 556 557
}

static int pkey_gost_mac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, EVP_MD_CTX *mctx)
	{
558 559
		unsigned int tmpsiglen=*siglen; /* for platforms where sizeof(int)!=sizeof(size_t)*/
		int ret;
560 561 562 563 564
		if (!sig) 
			{
			*siglen = 4;
			return 1;
			}
565 566 567
		ret=EVP_DigestFinal_ex(mctx,sig,&tmpsiglen);
		*siglen = tmpsiglen;
		return ret;
568
	}
569
/* ----------------------------------------------------------------*/
570 571
int register_pmeth_gost(int id, EVP_PKEY_METHOD **pmeth,int flags)
	{
572 573 574
	*pmeth = EVP_PKEY_meth_new(id, flags);
	if (!*pmeth) return 0;

575 576
	switch (id)
		{
577 578 579 580 581
		case NID_id_GostR3410_94:
			EVP_PKEY_meth_set_ctrl(*pmeth,pkey_gost_ctrl, pkey_gost_ctrl94_str);
			EVP_PKEY_meth_set_keygen(*pmeth,NULL,pkey_gost94cp_keygen);
			EVP_PKEY_meth_set_sign(*pmeth, NULL, pkey_gost94_cp_sign);
			EVP_PKEY_meth_set_verify(*pmeth, NULL, pkey_gost94_cp_verify);
582
			EVP_PKEY_meth_set_encrypt(*pmeth,
583
				pkey_gost_encrypt_init, pkey_GOST94cp_encrypt);
584
			EVP_PKEY_meth_set_decrypt(*pmeth, NULL, pkey_GOST94cp_decrypt);
585 586
			EVP_PKEY_meth_set_derive(*pmeth,
				pkey_gost_derive_init, pkey_gost94_derive);
587
			EVP_PKEY_meth_set_paramgen(*pmeth, pkey_gost_paramgen_init,pkey_gost94_paramgen);	
588 589 590 591 592 593 594 595
			break;
		case NID_id_GostR3410_2001:
			EVP_PKEY_meth_set_ctrl(*pmeth,pkey_gost_ctrl, pkey_gost_ctrl01_str);
			EVP_PKEY_meth_set_sign(*pmeth, NULL, pkey_gost01_cp_sign);
			EVP_PKEY_meth_set_verify(*pmeth, NULL, pkey_gost01_cp_verify);

			EVP_PKEY_meth_set_keygen(*pmeth, NULL, pkey_gost01cp_keygen);

596
			EVP_PKEY_meth_set_encrypt(*pmeth,
597
				pkey_gost_encrypt_init, pkey_GOST01cp_encrypt);
598
			EVP_PKEY_meth_set_decrypt(*pmeth, NULL, pkey_GOST01cp_decrypt);
599 600
			EVP_PKEY_meth_set_derive(*pmeth,
				pkey_gost_derive_init, pkey_gost2001_derive);
601
			EVP_PKEY_meth_set_paramgen(*pmeth, pkey_gost_paramgen_init,pkey_gost01_paramgen);	
602
			break;
603 604 605 606 607 608 609 610
		case NID_id_Gost28147_89_MAC:
			EVP_PKEY_meth_set_ctrl(*pmeth,pkey_gost_mac_ctrl, pkey_gost_mac_ctrl_str);
			EVP_PKEY_meth_set_signctx(*pmeth,pkey_gost_mac_signctx_init, pkey_gost_mac_signctx);
			EVP_PKEY_meth_set_keygen(*pmeth,NULL, pkey_gost_mac_keygen);
			EVP_PKEY_meth_set_init(*pmeth,pkey_gost_mac_init);
			EVP_PKEY_meth_set_cleanup(*pmeth,pkey_gost_mac_cleanup);
			EVP_PKEY_meth_set_copy(*pmeth,pkey_gost_mac_copy);
			return 1;
611
		default: /*Unsupported method*/
612
			return 0;
613
		}
614 615 616 617
	EVP_PKEY_meth_set_init(*pmeth, pkey_gost_init);
	EVP_PKEY_meth_set_cleanup(*pmeth, pkey_gost_cleanup);

	EVP_PKEY_meth_set_copy(*pmeth, pkey_gost_copy);
618
	/*FIXME derive etc...*/
619 620
	
	return 1;
621
	}
622