gost_ameth.c 22 KB

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