2
0

gost_ameth.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883
  1. /**********************************************************************
  2. * gost_ameth.c *
  3. * Copyright (c) 2005-2006 Cryptocom LTD *
  4. * This file is distributed under the same license as OpenSSL *
  5. * *
  6. * Implementation of RFC 4490/4491 ASN1 method *
  7. * for OpenSSL *
  8. * Requires OpenSSL 0.9.9 for compilation *
  9. **********************************************************************/
  10. #include <string.h>
  11. #include <openssl/crypto.h>
  12. #include <openssl/err.h>
  13. #include <openssl/engine.h>
  14. #include <openssl/evp.h>
  15. #include <openssl/asn1.h>
  16. #include "gost_params.h"
  17. #include "gost_lcl.h"
  18. #include "e_gost_err.h"
  19. int gost94_nid_by_params(DSA *p)
  20. {
  21. R3410_params *gost_params;
  22. BIGNUM *q = BN_new();
  23. for (gost_params = R3410_paramset; gost_params->q != NULL; gost_params++) {
  24. BN_dec2bn(&q, gost_params->q);
  25. if (!BN_cmp(q, p->q)) {
  26. BN_free(q);
  27. return gost_params->nid;
  28. }
  29. }
  30. BN_free(q);
  31. return NID_undef;
  32. }
  33. static ASN1_STRING *encode_gost_algor_params(const EVP_PKEY *key)
  34. {
  35. ASN1_STRING *params = ASN1_STRING_new();
  36. GOST_KEY_PARAMS *gkp = GOST_KEY_PARAMS_new();
  37. int pkey_param_nid = NID_undef;
  38. if (!params || !gkp) {
  39. GOSTerr(GOST_F_ENCODE_GOST_ALGOR_PARAMS, ERR_R_MALLOC_FAILURE);
  40. ASN1_STRING_free(params);
  41. params = NULL;
  42. goto err;
  43. }
  44. switch (EVP_PKEY_base_id(key)) {
  45. case NID_id_GostR3410_2001:
  46. pkey_param_nid =
  47. EC_GROUP_get_curve_name(EC_KEY_get0_group
  48. (EVP_PKEY_get0((EVP_PKEY *)key)));
  49. break;
  50. case NID_id_GostR3410_94:
  51. pkey_param_nid =
  52. (int)gost94_nid_by_params(EVP_PKEY_get0((EVP_PKEY *)key));
  53. if (pkey_param_nid == NID_undef) {
  54. GOSTerr(GOST_F_ENCODE_GOST_ALGOR_PARAMS,
  55. GOST_R_INVALID_GOST94_PARMSET);
  56. ASN1_STRING_free(params);
  57. params = NULL;
  58. goto err;
  59. }
  60. break;
  61. }
  62. gkp->key_params = OBJ_nid2obj(pkey_param_nid);
  63. gkp->hash_params = OBJ_nid2obj(NID_id_GostR3411_94_CryptoProParamSet);
  64. /*
  65. * gkp->cipher_params = OBJ_nid2obj(cipher_param_nid);
  66. */
  67. params->length = i2d_GOST_KEY_PARAMS(gkp, &params->data);
  68. if (params->length <= 0) {
  69. GOSTerr(GOST_F_ENCODE_GOST_ALGOR_PARAMS, ERR_R_MALLOC_FAILURE);
  70. ASN1_STRING_free(params);
  71. params = NULL;
  72. goto err;
  73. }
  74. params->type = V_ASN1_SEQUENCE;
  75. err:
  76. GOST_KEY_PARAMS_free(gkp);
  77. return params;
  78. }
  79. /*
  80. * Parses GOST algorithm parameters from X509_ALGOR and modifies pkey setting
  81. * NID and parameters
  82. */
  83. static int decode_gost_algor_params(EVP_PKEY *pkey, X509_ALGOR *palg)
  84. {
  85. ASN1_OBJECT *palg_obj = NULL;
  86. int ptype = V_ASN1_UNDEF;
  87. int pkey_nid = NID_undef, param_nid = NID_undef;
  88. void *_pval;
  89. ASN1_STRING *pval = NULL;
  90. const unsigned char *p;
  91. GOST_KEY_PARAMS *gkp = NULL;
  92. X509_ALGOR_get0(&palg_obj, &ptype, &_pval, palg);
  93. pval = _pval;
  94. if (ptype != V_ASN1_SEQUENCE) {
  95. GOSTerr(GOST_F_DECODE_GOST_ALGOR_PARAMS,
  96. GOST_R_BAD_KEY_PARAMETERS_FORMAT);
  97. return 0;
  98. }
  99. p = pval->data;
  100. pkey_nid = OBJ_obj2nid(palg_obj);
  101. gkp = d2i_GOST_KEY_PARAMS(NULL, &p, pval->length);
  102. if (!gkp) {
  103. GOSTerr(GOST_F_DECODE_GOST_ALGOR_PARAMS,
  104. GOST_R_BAD_PKEY_PARAMETERS_FORMAT);
  105. return 0;
  106. }
  107. param_nid = OBJ_obj2nid(gkp->key_params);
  108. GOST_KEY_PARAMS_free(gkp);
  109. EVP_PKEY_set_type(pkey, pkey_nid);
  110. switch (pkey_nid) {
  111. case NID_id_GostR3410_94:
  112. {
  113. DSA *dsa = EVP_PKEY_get0(pkey);
  114. if (!dsa) {
  115. dsa = DSA_new();
  116. if (!EVP_PKEY_assign(pkey, pkey_nid, dsa))
  117. return 0;
  118. }
  119. if (!fill_GOST94_params(dsa, param_nid))
  120. return 0;
  121. break;
  122. }
  123. case NID_id_GostR3410_2001:
  124. {
  125. EC_KEY *ec = EVP_PKEY_get0(pkey);
  126. if (!ec) {
  127. ec = EC_KEY_new();
  128. if (!EVP_PKEY_assign(pkey, pkey_nid, ec))
  129. return 0;
  130. }
  131. if (!fill_GOST2001_params(ec, param_nid))
  132. return 0;
  133. }
  134. }
  135. return 1;
  136. }
  137. static int gost_set_priv_key(EVP_PKEY *pkey, BIGNUM *priv)
  138. {
  139. switch (EVP_PKEY_base_id(pkey)) {
  140. case NID_id_GostR3410_94:
  141. {
  142. DSA *dsa = EVP_PKEY_get0(pkey);
  143. if (!dsa) {
  144. dsa = DSA_new();
  145. EVP_PKEY_assign(pkey, EVP_PKEY_base_id(pkey), dsa);
  146. }
  147. dsa->priv_key = BN_dup(priv);
  148. if (!EVP_PKEY_missing_parameters(pkey))
  149. gost94_compute_public(dsa);
  150. break;
  151. }
  152. case NID_id_GostR3410_2001:
  153. {
  154. EC_KEY *ec = EVP_PKEY_get0(pkey);
  155. if (!ec) {
  156. ec = EC_KEY_new();
  157. EVP_PKEY_assign(pkey, EVP_PKEY_base_id(pkey), ec);
  158. }
  159. if (!EC_KEY_set_private_key(ec, priv))
  160. return 0;
  161. if (!EVP_PKEY_missing_parameters(pkey))
  162. gost2001_compute_public(ec);
  163. break;
  164. }
  165. }
  166. return 1;
  167. }
  168. BIGNUM *gost_get0_priv_key(const EVP_PKEY *pkey)
  169. {
  170. switch (EVP_PKEY_base_id(pkey)) {
  171. case NID_id_GostR3410_94:
  172. {
  173. DSA *dsa = EVP_PKEY_get0((EVP_PKEY *)pkey);
  174. if (!dsa) {
  175. return NULL;
  176. }
  177. if (!dsa->priv_key)
  178. return NULL;
  179. return dsa->priv_key;
  180. break;
  181. }
  182. case NID_id_GostR3410_2001:
  183. {
  184. EC_KEY *ec = EVP_PKEY_get0((EVP_PKEY *)pkey);
  185. const BIGNUM *priv;
  186. if (!ec) {
  187. return NULL;
  188. }
  189. if (!(priv = EC_KEY_get0_private_key(ec)))
  190. return NULL;
  191. return (BIGNUM *)priv;
  192. break;
  193. }
  194. }
  195. return NULL;
  196. }
  197. static int pkey_ctrl_gost(EVP_PKEY *pkey, int op, long arg1, void *arg2)
  198. {
  199. switch (op) {
  200. case ASN1_PKEY_CTRL_PKCS7_SIGN:
  201. if (arg1 == 0) {
  202. X509_ALGOR *alg1 = NULL, *alg2 = NULL;
  203. int nid = EVP_PKEY_base_id(pkey);
  204. PKCS7_SIGNER_INFO_get0_algs((PKCS7_SIGNER_INFO *)arg2,
  205. NULL, &alg1, &alg2);
  206. X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_id_GostR3411_94),
  207. V_ASN1_NULL, 0);
  208. if (nid == NID_undef) {
  209. return (-1);
  210. }
  211. X509_ALGOR_set0(alg2, OBJ_nid2obj(nid), V_ASN1_NULL, 0);
  212. }
  213. return 1;
  214. case ASN1_PKEY_CTRL_PKCS7_ENCRYPT:
  215. if (arg1 == 0) {
  216. X509_ALGOR *alg;
  217. ASN1_STRING *params = encode_gost_algor_params(pkey);
  218. if (!params) {
  219. return -1;
  220. }
  221. PKCS7_RECIP_INFO_get0_alg((PKCS7_RECIP_INFO *)arg2, &alg);
  222. X509_ALGOR_set0(alg, OBJ_nid2obj(pkey->type),
  223. V_ASN1_SEQUENCE, params);
  224. }
  225. return 1;
  226. case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
  227. *(int *)arg2 = NID_id_GostR3411_94;
  228. return 2;
  229. }
  230. return -2;
  231. }
  232. /* --------------------- free functions * ------------------------------*/
  233. static void pkey_free_gost94(EVP_PKEY *key)
  234. {
  235. if (key->pkey.dsa) {
  236. DSA_free(key->pkey.dsa);
  237. }
  238. }
  239. static void pkey_free_gost01(EVP_PKEY *key)
  240. {
  241. if (key->pkey.ec) {
  242. EC_KEY_free(key->pkey.ec);
  243. }
  244. }
  245. /* ------------------ private key functions -----------------------------*/
  246. static int priv_decode_gost(EVP_PKEY *pk, PKCS8_PRIV_KEY_INFO *p8inf)
  247. {
  248. const unsigned char *pkey_buf = NULL, *p = NULL;
  249. int priv_len = 0;
  250. BIGNUM *pk_num = NULL;
  251. int ret = 0;
  252. X509_ALGOR *palg = NULL;
  253. ASN1_OBJECT *palg_obj = NULL;
  254. ASN1_INTEGER *priv_key = NULL;
  255. if (!PKCS8_pkey_get0(&palg_obj, &pkey_buf, &priv_len, &palg, p8inf))
  256. return 0;
  257. p = pkey_buf;
  258. if (!decode_gost_algor_params(pk, palg)) {
  259. return 0;
  260. }
  261. if (V_ASN1_OCTET_STRING == *p) {
  262. /* New format - Little endian octet string */
  263. unsigned char rev_buf[32];
  264. int i;
  265. ASN1_OCTET_STRING *s = d2i_ASN1_OCTET_STRING(NULL, &p, priv_len);
  266. if (!s || s->length != 32) {
  267. GOSTerr(GOST_F_PRIV_DECODE_GOST, EVP_R_DECODE_ERROR);
  268. return 0;
  269. }
  270. for (i = 0; i < 32; i++) {
  271. rev_buf[31 - i] = s->data[i];
  272. }
  273. ASN1_STRING_free(s);
  274. pk_num = getbnfrombuf(rev_buf, 32);
  275. } else {
  276. priv_key = d2i_ASN1_INTEGER(NULL, &p, priv_len);
  277. if (!priv_key)
  278. return 0;
  279. ret = ((pk_num = ASN1_INTEGER_to_BN(priv_key, NULL)) != NULL);
  280. ASN1_INTEGER_free(priv_key);
  281. if (!ret) {
  282. GOSTerr(GOST_F_PRIV_DECODE_GOST, EVP_R_DECODE_ERROR);
  283. return 0;
  284. }
  285. }
  286. ret = gost_set_priv_key(pk, pk_num);
  287. BN_free(pk_num);
  288. return ret;
  289. }
  290. /* ----------------------------------------------------------------------*/
  291. static int priv_encode_gost(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk)
  292. {
  293. ASN1_OBJECT *algobj = OBJ_nid2obj(EVP_PKEY_base_id(pk));
  294. ASN1_STRING *params = encode_gost_algor_params(pk);
  295. unsigned char *priv_buf = NULL;
  296. int priv_len;
  297. ASN1_INTEGER *asn1key = NULL;
  298. if (!params) {
  299. return 0;
  300. }
  301. asn1key = BN_to_ASN1_INTEGER(gost_get0_priv_key(pk), NULL);
  302. priv_len = i2d_ASN1_INTEGER(asn1key, &priv_buf);
  303. ASN1_INTEGER_free(asn1key);
  304. return PKCS8_pkey_set0(p8, algobj, 0, V_ASN1_SEQUENCE, params,
  305. priv_buf, priv_len);
  306. }
  307. /* --------- printing keys --------------------------------*/
  308. static int print_gost_94(BIO *out, const EVP_PKEY *pkey, int indent,
  309. ASN1_PCTX *pctx, int type)
  310. {
  311. int param_nid = NID_undef;
  312. if (type == 2) {
  313. BIGNUM *key;
  314. if (!BIO_indent(out, indent, 128))
  315. return 0;
  316. BIO_printf(out, "Private key: ");
  317. key = gost_get0_priv_key(pkey);
  318. if (!key)
  319. BIO_printf(out, "<undefined>");
  320. else
  321. BN_print(out, key);
  322. BIO_printf(out, "\n");
  323. }
  324. if (type >= 1) {
  325. BIGNUM *pubkey;
  326. pubkey = ((DSA *)EVP_PKEY_get0((EVP_PKEY *)pkey))->pub_key;
  327. BIO_indent(out, indent, 128);
  328. BIO_printf(out, "Public key: ");
  329. BN_print(out, pubkey);
  330. BIO_printf(out, "\n");
  331. }
  332. param_nid = gost94_nid_by_params(EVP_PKEY_get0((EVP_PKEY *)pkey));
  333. BIO_indent(out, indent, 128);
  334. BIO_printf(out, "Parameter set: %s\n", OBJ_nid2ln(param_nid));
  335. return 1;
  336. }
  337. static int param_print_gost94(BIO *out, const EVP_PKEY *pkey, int indent,
  338. ASN1_PCTX *pctx)
  339. {
  340. return print_gost_94(out, pkey, indent, pctx, 0);
  341. }
  342. static int pub_print_gost94(BIO *out, const EVP_PKEY *pkey, int indent,
  343. ASN1_PCTX *pctx)
  344. {
  345. return print_gost_94(out, pkey, indent, pctx, 1);
  346. }
  347. static int priv_print_gost94(BIO *out, const EVP_PKEY *pkey, int indent,
  348. ASN1_PCTX *pctx)
  349. {
  350. return print_gost_94(out, pkey, indent, pctx, 2);
  351. }
  352. static int print_gost_01(BIO *out, const EVP_PKEY *pkey, int indent,
  353. ASN1_PCTX *pctx, int type)
  354. {
  355. int param_nid = NID_undef;
  356. if (type == 2) {
  357. BIGNUM *key;
  358. if (!BIO_indent(out, indent, 128))
  359. return 0;
  360. BIO_printf(out, "Private key: ");
  361. key = gost_get0_priv_key(pkey);
  362. if (!key)
  363. BIO_printf(out, "<undefined)");
  364. else
  365. BN_print(out, key);
  366. BIO_printf(out, "\n");
  367. }
  368. if (type >= 1) {
  369. BN_CTX *ctx = BN_CTX_new();
  370. BIGNUM *X, *Y;
  371. const EC_POINT *pubkey;
  372. const EC_GROUP *group;
  373. if (!ctx) {
  374. GOSTerr(GOST_F_PRINT_GOST_01, ERR_R_MALLOC_FAILURE);
  375. return 0;
  376. }
  377. BN_CTX_start(ctx);
  378. X = BN_CTX_get(ctx);
  379. Y = BN_CTX_get(ctx);
  380. pubkey =
  381. EC_KEY_get0_public_key((EC_KEY *)EVP_PKEY_get0((EVP_PKEY *)pkey));
  382. group = EC_KEY_get0_group((EC_KEY *)EVP_PKEY_get0((EVP_PKEY *)pkey));
  383. if (!EC_POINT_get_affine_coordinates_GFp(group, pubkey, X, Y, ctx)) {
  384. GOSTerr(GOST_F_PRINT_GOST_01, ERR_R_EC_LIB);
  385. BN_CTX_free(ctx);
  386. return 0;
  387. }
  388. if (!BIO_indent(out, indent, 128))
  389. return 0;
  390. BIO_printf(out, "Public key:\n");
  391. if (!BIO_indent(out, indent + 3, 128))
  392. return 0;
  393. BIO_printf(out, "X:");
  394. BN_print(out, X);
  395. BIO_printf(out, "\n");
  396. BIO_indent(out, indent + 3, 128);
  397. BIO_printf(out, "Y:");
  398. BN_print(out, Y);
  399. BIO_printf(out, "\n");
  400. BN_CTX_end(ctx);
  401. BN_CTX_free(ctx);
  402. }
  403. param_nid =
  404. EC_GROUP_get_curve_name(EC_KEY_get0_group
  405. (EVP_PKEY_get0((EVP_PKEY *)pkey)));
  406. if (!BIO_indent(out, indent, 128))
  407. return 0;
  408. BIO_printf(out, "Parameter set: %s\n", OBJ_nid2ln(param_nid));
  409. return 1;
  410. }
  411. static int param_print_gost01(BIO *out, const EVP_PKEY *pkey, int indent,
  412. ASN1_PCTX *pctx)
  413. {
  414. return print_gost_01(out, pkey, indent, pctx, 0);
  415. }
  416. static int pub_print_gost01(BIO *out, const EVP_PKEY *pkey, int indent,
  417. ASN1_PCTX *pctx)
  418. {
  419. return print_gost_01(out, pkey, indent, pctx, 1);
  420. }
  421. static int priv_print_gost01(BIO *out, const EVP_PKEY *pkey, int indent,
  422. ASN1_PCTX *pctx)
  423. {
  424. return print_gost_01(out, pkey, indent, pctx, 2);
  425. }
  426. /* ---------------------------------------------------------------------*/
  427. static int param_missing_gost94(const EVP_PKEY *pk)
  428. {
  429. const DSA *dsa = EVP_PKEY_get0((EVP_PKEY *)pk);
  430. if (!dsa)
  431. return 1;
  432. if (!dsa->q)
  433. return 1;
  434. return 0;
  435. }
  436. static int param_missing_gost01(const EVP_PKEY *pk)
  437. {
  438. const EC_KEY *ec = EVP_PKEY_get0((EVP_PKEY *)pk);
  439. if (!ec)
  440. return 1;
  441. if (!EC_KEY_get0_group(ec))
  442. return 1;
  443. return 0;
  444. }
  445. static int param_copy_gost94(EVP_PKEY *to, const EVP_PKEY *from)
  446. {
  447. const DSA *dfrom = EVP_PKEY_get0((EVP_PKEY *)from);
  448. DSA *dto = EVP_PKEY_get0(to);
  449. if (EVP_PKEY_base_id(from) != EVP_PKEY_base_id(to)) {
  450. GOSTerr(GOST_F_PARAM_COPY_GOST94, GOST_R_INCOMPATIBLE_ALGORITHMS);
  451. return 0;
  452. }
  453. if (!dfrom) {
  454. GOSTerr(GOST_F_PARAM_COPY_GOST94, GOST_R_KEY_PARAMETERS_MISSING);
  455. return 0;
  456. }
  457. if (!dto) {
  458. dto = DSA_new();
  459. EVP_PKEY_assign(to, EVP_PKEY_base_id(from), dto);
  460. }
  461. #define COPYBIGNUM(a,b,x) if (a->x) BN_free(a->x); a->x=BN_dup(b->x);
  462. COPYBIGNUM(dto, dfrom, p)
  463. COPYBIGNUM(dto, dfrom, q)
  464. COPYBIGNUM(dto, dfrom, g)
  465. if (dto->priv_key)
  466. gost94_compute_public(dto);
  467. return 1;
  468. }
  469. static int param_copy_gost01(EVP_PKEY *to, const EVP_PKEY *from)
  470. {
  471. EC_KEY *eto = EVP_PKEY_get0(to);
  472. const EC_KEY *efrom = EVP_PKEY_get0((EVP_PKEY *)from);
  473. if (EVP_PKEY_base_id(from) != EVP_PKEY_base_id(to)) {
  474. GOSTerr(GOST_F_PARAM_COPY_GOST01, GOST_R_INCOMPATIBLE_ALGORITHMS);
  475. return 0;
  476. }
  477. if (!efrom) {
  478. GOSTerr(GOST_F_PARAM_COPY_GOST01, GOST_R_KEY_PARAMETERS_MISSING);
  479. return 0;
  480. }
  481. if (!eto) {
  482. eto = EC_KEY_new();
  483. EVP_PKEY_assign(to, EVP_PKEY_base_id(from), eto);
  484. }
  485. EC_KEY_set_group(eto, EC_KEY_get0_group(efrom));
  486. if (EC_KEY_get0_private_key(eto)) {
  487. gost2001_compute_public(eto);
  488. }
  489. return 1;
  490. }
  491. static int param_cmp_gost94(const EVP_PKEY *a, const EVP_PKEY *b)
  492. {
  493. const DSA *da = EVP_PKEY_get0((EVP_PKEY *)a);
  494. const DSA *db = EVP_PKEY_get0((EVP_PKEY *)b);
  495. if (!BN_cmp(da->q, db->q))
  496. return 1;
  497. return 0;
  498. }
  499. static int param_cmp_gost01(const EVP_PKEY *a, const EVP_PKEY *b)
  500. {
  501. if (EC_GROUP_get_curve_name
  502. (EC_KEY_get0_group(EVP_PKEY_get0((EVP_PKEY *)a))) ==
  503. EC_GROUP_get_curve_name(EC_KEY_get0_group
  504. (EVP_PKEY_get0((EVP_PKEY *)b)))) {
  505. return 1;
  506. }
  507. return 0;
  508. }
  509. /* ---------- Public key functions * --------------------------------------*/
  510. static int pub_decode_gost94(EVP_PKEY *pk, X509_PUBKEY *pub)
  511. {
  512. X509_ALGOR *palg = NULL;
  513. const unsigned char *pubkey_buf = NULL;
  514. unsigned char *databuf;
  515. ASN1_OBJECT *palgobj = NULL;
  516. int pub_len, i, j;
  517. DSA *dsa;
  518. ASN1_OCTET_STRING *octet = NULL;
  519. if (!X509_PUBKEY_get0_param(&palgobj, &pubkey_buf, &pub_len, &palg, pub))
  520. return 0;
  521. EVP_PKEY_assign(pk, OBJ_obj2nid(palgobj), NULL);
  522. if (!decode_gost_algor_params(pk, palg))
  523. return 0;
  524. octet = d2i_ASN1_OCTET_STRING(NULL, &pubkey_buf, pub_len);
  525. if (!octet) {
  526. GOSTerr(GOST_F_PUB_DECODE_GOST94, ERR_R_MALLOC_FAILURE);
  527. return 0;
  528. }
  529. databuf = OPENSSL_malloc(octet->length);
  530. for (i = 0, j = octet->length - 1; i < octet->length; i++, j--) {
  531. databuf[j] = octet->data[i];
  532. }
  533. dsa = EVP_PKEY_get0(pk);
  534. dsa->pub_key = BN_bin2bn(databuf, octet->length, NULL);
  535. ASN1_OCTET_STRING_free(octet);
  536. OPENSSL_free(databuf);
  537. return 1;
  538. }
  539. static int pub_encode_gost94(X509_PUBKEY *pub, const EVP_PKEY *pk)
  540. {
  541. ASN1_OBJECT *algobj = NULL;
  542. ASN1_OCTET_STRING *octet = NULL;
  543. void *pval = NULL;
  544. unsigned char *buf = NULL, *databuf, *sptr;
  545. int i, j, data_len, ret = 0;
  546. int ptype = V_ASN1_UNDEF;
  547. DSA *dsa = EVP_PKEY_get0((EVP_PKEY *)pk);
  548. algobj = OBJ_nid2obj(EVP_PKEY_base_id(pk));
  549. if (pk->save_parameters) {
  550. ASN1_STRING *params = encode_gost_algor_params(pk);
  551. pval = params;
  552. ptype = V_ASN1_SEQUENCE;
  553. }
  554. data_len = BN_num_bytes(dsa->pub_key);
  555. databuf = OPENSSL_malloc(data_len);
  556. BN_bn2bin(dsa->pub_key, databuf);
  557. octet = ASN1_OCTET_STRING_new();
  558. ASN1_STRING_set(octet, NULL, data_len);
  559. sptr = ASN1_STRING_data(octet);
  560. for (i = 0, j = data_len - 1; i < data_len; i++, j--) {
  561. sptr[i] = databuf[j];
  562. }
  563. OPENSSL_free(databuf);
  564. ret = i2d_ASN1_OCTET_STRING(octet, &buf);
  565. ASN1_BIT_STRING_free(octet);
  566. if (ret < 0)
  567. return 0;
  568. return X509_PUBKEY_set0_param(pub, algobj, ptype, pval, buf, ret);
  569. }
  570. static int pub_decode_gost01(EVP_PKEY *pk, X509_PUBKEY *pub)
  571. {
  572. X509_ALGOR *palg = NULL;
  573. const unsigned char *pubkey_buf = NULL;
  574. unsigned char *databuf;
  575. ASN1_OBJECT *palgobj = NULL;
  576. int pub_len, i, j;
  577. EC_POINT *pub_key;
  578. BIGNUM *X, *Y;
  579. ASN1_OCTET_STRING *octet = NULL;
  580. int len;
  581. const EC_GROUP *group;
  582. if (!X509_PUBKEY_get0_param(&palgobj, &pubkey_buf, &pub_len, &palg, pub))
  583. return 0;
  584. EVP_PKEY_assign(pk, OBJ_obj2nid(palgobj), NULL);
  585. if (!decode_gost_algor_params(pk, palg))
  586. return 0;
  587. group = EC_KEY_get0_group(EVP_PKEY_get0(pk));
  588. octet = d2i_ASN1_OCTET_STRING(NULL, &pubkey_buf, pub_len);
  589. if (!octet) {
  590. GOSTerr(GOST_F_PUB_DECODE_GOST01, ERR_R_MALLOC_FAILURE);
  591. return 0;
  592. }
  593. databuf = OPENSSL_malloc(octet->length);
  594. for (i = 0, j = octet->length - 1; i < octet->length; i++, j--) {
  595. databuf[j] = octet->data[i];
  596. }
  597. len = octet->length / 2;
  598. ASN1_OCTET_STRING_free(octet);
  599. Y = getbnfrombuf(databuf, len);
  600. X = getbnfrombuf(databuf + len, len);
  601. OPENSSL_free(databuf);
  602. pub_key = EC_POINT_new(group);
  603. if (!EC_POINT_set_affine_coordinates_GFp(group, pub_key, X, Y, NULL)) {
  604. GOSTerr(GOST_F_PUB_DECODE_GOST01, ERR_R_EC_LIB);
  605. EC_POINT_free(pub_key);
  606. BN_free(X);
  607. BN_free(Y);
  608. return 0;
  609. }
  610. BN_free(X);
  611. BN_free(Y);
  612. if (!EC_KEY_set_public_key(EVP_PKEY_get0(pk), pub_key)) {
  613. GOSTerr(GOST_F_PUB_DECODE_GOST01, ERR_R_EC_LIB);
  614. EC_POINT_free(pub_key);
  615. return 0;
  616. }
  617. EC_POINT_free(pub_key);
  618. return 1;
  619. }
  620. static int pub_encode_gost01(X509_PUBKEY *pub, const EVP_PKEY *pk)
  621. {
  622. ASN1_OBJECT *algobj = NULL;
  623. ASN1_OCTET_STRING *octet = NULL;
  624. void *pval = NULL;
  625. unsigned char *buf = NULL, *databuf, *sptr;
  626. int i, j, data_len, ret = 0;
  627. const EC_POINT *pub_key;
  628. BIGNUM *X, *Y, *order;
  629. const EC_KEY *ec = EVP_PKEY_get0((EVP_PKEY *)pk);
  630. int ptype = V_ASN1_UNDEF;
  631. algobj = OBJ_nid2obj(EVP_PKEY_base_id(pk));
  632. if (pk->save_parameters) {
  633. ASN1_STRING *params = encode_gost_algor_params(pk);
  634. pval = params;
  635. ptype = V_ASN1_SEQUENCE;
  636. }
  637. order = BN_new();
  638. EC_GROUP_get_order(EC_KEY_get0_group(ec), order, NULL);
  639. pub_key = EC_KEY_get0_public_key(ec);
  640. if (!pub_key) {
  641. GOSTerr(GOST_F_PUB_ENCODE_GOST01, GOST_R_PUBLIC_KEY_UNDEFINED);
  642. return 0;
  643. }
  644. X = BN_new();
  645. Y = BN_new();
  646. EC_POINT_get_affine_coordinates_GFp(EC_KEY_get0_group(ec),
  647. pub_key, X, Y, NULL);
  648. data_len = 2 * BN_num_bytes(order);
  649. BN_free(order);
  650. databuf = OPENSSL_malloc(data_len);
  651. memset(databuf, 0, data_len);
  652. store_bignum(X, databuf + data_len / 2, data_len / 2);
  653. store_bignum(Y, databuf, data_len / 2);
  654. BN_free(X);
  655. BN_free(Y);
  656. octet = ASN1_OCTET_STRING_new();
  657. ASN1_STRING_set(octet, NULL, data_len);
  658. sptr = ASN1_STRING_data(octet);
  659. for (i = 0, j = data_len - 1; i < data_len; i++, j--) {
  660. sptr[i] = databuf[j];
  661. }
  662. OPENSSL_free(databuf);
  663. ret = i2d_ASN1_OCTET_STRING(octet, &buf);
  664. ASN1_BIT_STRING_free(octet);
  665. if (ret < 0)
  666. return 0;
  667. return X509_PUBKEY_set0_param(pub, algobj, ptype, pval, buf, ret);
  668. }
  669. static int pub_cmp_gost94(const EVP_PKEY *a, const EVP_PKEY *b)
  670. {
  671. const DSA *da = EVP_PKEY_get0((EVP_PKEY *)a);
  672. const DSA *db = EVP_PKEY_get0((EVP_PKEY *)b);
  673. if (da && db && da->pub_key && db->pub_key
  674. && !BN_cmp(da->pub_key, db->pub_key)) {
  675. return 1;
  676. }
  677. return 0;
  678. }
  679. static int pub_cmp_gost01(const EVP_PKEY *a, const EVP_PKEY *b)
  680. {
  681. const EC_KEY *ea = EVP_PKEY_get0((EVP_PKEY *)a);
  682. const EC_KEY *eb = EVP_PKEY_get0((EVP_PKEY *)b);
  683. const EC_POINT *ka, *kb;
  684. int ret = 0;
  685. if (!ea || !eb)
  686. return 0;
  687. ka = EC_KEY_get0_public_key(ea);
  688. kb = EC_KEY_get0_public_key(eb);
  689. if (!ka || !kb)
  690. return 0;
  691. ret = (0 == EC_POINT_cmp(EC_KEY_get0_group(ea), ka, kb, NULL));
  692. return ret;
  693. }
  694. static int pkey_size_gost(const EVP_PKEY *pk)
  695. {
  696. return 64;
  697. }
  698. static int pkey_bits_gost(const EVP_PKEY *pk)
  699. {
  700. return 256;
  701. }
  702. /* ---------------------- ASN1 METHOD for GOST MAC -------------------*/
  703. static void mackey_free_gost(EVP_PKEY *pk)
  704. {
  705. if (pk->pkey.ptr) {
  706. OPENSSL_free(pk->pkey.ptr);
  707. }
  708. }
  709. static int mac_ctrl_gost(EVP_PKEY *pkey, int op, long arg1, void *arg2)
  710. {
  711. switch (op) {
  712. case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
  713. *(int *)arg2 = NID_id_Gost28147_89_MAC;
  714. return 2;
  715. }
  716. return -2;
  717. }
  718. static int gost94_param_encode(const EVP_PKEY *pkey, unsigned char **pder)
  719. {
  720. int nid = gost94_nid_by_params(EVP_PKEY_get0((EVP_PKEY *)pkey));
  721. return i2d_ASN1_OBJECT(OBJ_nid2obj(nid), pder);
  722. }
  723. static int gost2001_param_encode(const EVP_PKEY *pkey, unsigned char **pder)
  724. {
  725. int nid =
  726. EC_GROUP_get_curve_name(EC_KEY_get0_group
  727. (EVP_PKEY_get0((EVP_PKEY *)pkey)));
  728. return i2d_ASN1_OBJECT(OBJ_nid2obj(nid), pder);
  729. }
  730. static int gost94_param_decode(EVP_PKEY *pkey, const unsigned char **pder,
  731. int derlen)
  732. {
  733. ASN1_OBJECT *obj = NULL;
  734. DSA *dsa = EVP_PKEY_get0(pkey);
  735. int nid;
  736. if (d2i_ASN1_OBJECT(&obj, pder, derlen) == NULL) {
  737. return 0;
  738. }
  739. nid = OBJ_obj2nid(obj);
  740. ASN1_OBJECT_free(obj);
  741. if (!dsa) {
  742. dsa = DSA_new();
  743. if (!EVP_PKEY_assign(pkey, NID_id_GostR3410_94, dsa))
  744. return 0;
  745. }
  746. if (!fill_GOST94_params(dsa, nid))
  747. return 0;
  748. return 1;
  749. }
  750. static int gost2001_param_decode(EVP_PKEY *pkey, const unsigned char **pder,
  751. int derlen)
  752. {
  753. ASN1_OBJECT *obj = NULL;
  754. int nid;
  755. EC_KEY *ec = EVP_PKEY_get0(pkey);
  756. if (d2i_ASN1_OBJECT(&obj, pder, derlen) == NULL) {
  757. return 0;
  758. }
  759. nid = OBJ_obj2nid(obj);
  760. ASN1_OBJECT_free(obj);
  761. if (!ec) {
  762. ec = EC_KEY_new();
  763. if (!EVP_PKEY_assign(pkey, NID_id_GostR3410_2001, ec))
  764. return 0;
  765. }
  766. if (!fill_GOST2001_params(ec, nid))
  767. return 0;
  768. return 1;
  769. }
  770. /* ----------------------------------------------------------------------*/
  771. int register_ameth_gost(int nid, EVP_PKEY_ASN1_METHOD **ameth,
  772. const char *pemstr, const char *info)
  773. {
  774. *ameth = EVP_PKEY_asn1_new(nid, ASN1_PKEY_SIGPARAM_NULL, pemstr, info);
  775. if (!*ameth)
  776. return 0;
  777. switch (nid) {
  778. case NID_id_GostR3410_94:
  779. EVP_PKEY_asn1_set_free(*ameth, pkey_free_gost94);
  780. EVP_PKEY_asn1_set_private(*ameth,
  781. priv_decode_gost, priv_encode_gost,
  782. priv_print_gost94);
  783. EVP_PKEY_asn1_set_param(*ameth,
  784. gost94_param_decode, gost94_param_encode,
  785. param_missing_gost94, param_copy_gost94,
  786. param_cmp_gost94, param_print_gost94);
  787. EVP_PKEY_asn1_set_public(*ameth,
  788. pub_decode_gost94, pub_encode_gost94,
  789. pub_cmp_gost94, pub_print_gost94,
  790. pkey_size_gost, pkey_bits_gost);
  791. EVP_PKEY_asn1_set_ctrl(*ameth, pkey_ctrl_gost);
  792. break;
  793. case NID_id_GostR3410_2001:
  794. EVP_PKEY_asn1_set_free(*ameth, pkey_free_gost01);
  795. EVP_PKEY_asn1_set_private(*ameth,
  796. priv_decode_gost, priv_encode_gost,
  797. priv_print_gost01);
  798. EVP_PKEY_asn1_set_param(*ameth,
  799. gost2001_param_decode, gost2001_param_encode,
  800. param_missing_gost01, param_copy_gost01,
  801. param_cmp_gost01, param_print_gost01);
  802. EVP_PKEY_asn1_set_public(*ameth,
  803. pub_decode_gost01, pub_encode_gost01,
  804. pub_cmp_gost01, pub_print_gost01,
  805. pkey_size_gost, pkey_bits_gost);
  806. EVP_PKEY_asn1_set_ctrl(*ameth, pkey_ctrl_gost);
  807. break;
  808. case NID_id_Gost28147_89_MAC:
  809. EVP_PKEY_asn1_set_free(*ameth, mackey_free_gost);
  810. EVP_PKEY_asn1_set_ctrl(*ameth, mac_ctrl_gost);
  811. break;
  812. }
  813. return 1;
  814. }