gost_pmeth.c 19 KB

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