gost_pmeth.c 16 KB

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