gost2001.c 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343
  1. /**********************************************************************
  2. * gost2001.c *
  3. * Copyright (c) 2005-2006 Cryptocom LTD *
  4. * This file is distributed under the same license as OpenSSL *
  5. * *
  6. * Implementation of GOST R 34.10-2001 *
  7. * Requires OpenSSL 0.9.9 for compilation *
  8. **********************************************************************/
  9. #include "gost_lcl.h"
  10. #include "gost_params.h"
  11. #include <string.h>
  12. #include <openssl/rand.h>
  13. #include <openssl/ecdsa.h>
  14. #include <openssl/err.h>
  15. #include "e_gost_err.h"
  16. #ifdef DEBUG_SIGN
  17. extern
  18. void dump_signature(const char *message,const unsigned char *buffer,size_t len);
  19. void dump_dsa_sig(const char *message, DSA_SIG *sig);
  20. #else
  21. #define dump_signature(a,b,c)
  22. #define dump_dsa_sig(a,b)
  23. #endif
  24. /*
  25. * Fills EC_KEY structure hidden in the app_data field of DSA structure
  26. * with parameter information, extracted from parameter array in
  27. * params.c file.
  28. *
  29. * Also fils DSA->q field with copy of EC_GROUP order field to make
  30. * DSA_size function work
  31. */
  32. int fill_GOST2001_params(EC_KEY *eckey, int nid)
  33. {
  34. R3410_2001_params *params = R3410_2001_paramset;
  35. EC_GROUP *grp=NULL;
  36. BIGNUM *p=NULL,*q=NULL,*a=NULL,*b=NULL,*x=NULL,*y=NULL;
  37. EC_POINT *P=NULL;
  38. BN_CTX *ctx=BN_CTX_new();
  39. int ok=0;
  40. BN_CTX_start(ctx);
  41. p=BN_CTX_get(ctx);
  42. a=BN_CTX_get(ctx);
  43. b=BN_CTX_get(ctx);
  44. x=BN_CTX_get(ctx);
  45. y=BN_CTX_get(ctx);
  46. q=BN_CTX_get(ctx);
  47. while (params->nid!=NID_undef && params->nid != nid) params++;
  48. if (params->nid == NID_undef)
  49. {
  50. GOSTerr(GOST_F_FILL_GOST2001_PARAMS,GOST_R_UNSUPPORTED_PARAMETER_SET);
  51. goto err;
  52. }
  53. BN_hex2bn(&p,params->p);
  54. BN_hex2bn(&a,params->a);
  55. BN_hex2bn(&b,params->b);
  56. grp = EC_GROUP_new_curve_GFp(p,a,b,ctx);
  57. P = EC_POINT_new(grp);
  58. BN_hex2bn(&x,params->x);
  59. BN_hex2bn(&y,params->y);
  60. EC_POINT_set_affine_coordinates_GFp(grp,P,x,y,ctx);
  61. BN_hex2bn(&q,params->q);
  62. #ifdef DEBUG_KEYS
  63. fprintf(stderr,"Set params index %d oid %s\nq=",
  64. (params-R3410_2001_paramset),OBJ_nid2sn(params->nid));
  65. BN_print_fp(stderr,q);
  66. fprintf(stderr,"\n");
  67. #endif
  68. EC_GROUP_set_generator(grp,P,q,NULL);
  69. EC_GROUP_set_curve_name(grp,params->nid);
  70. EC_KEY_set_group(eckey,grp);
  71. ok=1;
  72. err:
  73. EC_POINT_free(P);
  74. EC_GROUP_free(grp);
  75. BN_CTX_end(ctx);
  76. BN_CTX_free(ctx);
  77. return ok;
  78. }
  79. /*
  80. * Computes gost2001 signature as DSA_SIG structure
  81. *
  82. *
  83. */
  84. DSA_SIG *gost2001_do_sign(const unsigned char *dgst,int dlen, EC_KEY *eckey)
  85. {
  86. DSA_SIG *newsig = NULL;
  87. BIGNUM *md = hashsum2bn(dgst);
  88. BIGNUM *order = NULL;
  89. const EC_GROUP *group;
  90. const BIGNUM *priv_key;
  91. BIGNUM *r=NULL,*s=NULL,*X=NULL,*tmp=NULL,*tmp2=NULL, *k=NULL,*e=NULL;
  92. EC_POINT *C=NULL;
  93. BN_CTX *ctx = BN_CTX_new();
  94. BN_CTX_start(ctx);
  95. OPENSSL_assert(dlen==32);
  96. newsig=DSA_SIG_new();
  97. if (!newsig)
  98. {
  99. GOSTerr(GOST_F_GOST2001_DO_SIGN,GOST_R_NO_MEMORY);
  100. goto err;
  101. }
  102. group = EC_KEY_get0_group(eckey);
  103. order=BN_CTX_get(ctx);
  104. EC_GROUP_get_order(group,order,ctx);
  105. priv_key = EC_KEY_get0_private_key(eckey);
  106. e = BN_CTX_get(ctx);
  107. BN_mod(e,md,order,ctx);
  108. #ifdef DEBUG_SIGN
  109. fprintf(stderr,"digest as bignum=");
  110. BN_print_fp(stderr,md);
  111. fprintf(stderr,"\ndigest mod q=");
  112. BN_print_fp(stderr,e);
  113. fprintf(stderr,"\n");
  114. #endif
  115. if (BN_is_zero(e))
  116. {
  117. BN_one(e);
  118. }
  119. k =BN_CTX_get(ctx);
  120. C=EC_POINT_new(group);
  121. do
  122. {
  123. do
  124. {
  125. if (!BN_rand_range(k,order))
  126. {
  127. GOSTerr(GOST_F_GOST2001_DO_SIGN,GOST_R_RANDOM_NUMBER_GENERATOR_FAILED);
  128. DSA_SIG_free(newsig);
  129. newsig = NULL;
  130. goto err;
  131. }
  132. if (!EC_POINT_mul(group,C,k,NULL,NULL,ctx))
  133. {
  134. GOSTerr(GOST_F_GOST2001_DO_SIGN,ERR_R_EC_LIB);
  135. DSA_SIG_free(newsig);
  136. newsig = NULL;
  137. goto err;
  138. }
  139. if (!X) X=BN_CTX_get(ctx);
  140. if (!EC_POINT_get_affine_coordinates_GFp(group,C,X,NULL,ctx))
  141. {
  142. GOSTerr(GOST_F_GOST2001_DO_SIGN,ERR_R_EC_LIB);
  143. DSA_SIG_free(newsig);
  144. newsig = NULL;
  145. goto err;
  146. }
  147. if (!r) r=BN_CTX_get(ctx);
  148. BN_nnmod(r,X,order,ctx);
  149. }
  150. while (BN_is_zero(r));
  151. /* s = (r*priv_key+k*e) mod order */
  152. if (!tmp) tmp = BN_CTX_get(ctx);
  153. BN_mod_mul(tmp,priv_key,r,order,ctx);
  154. if (!tmp2) tmp2 = BN_CTX_get(ctx);
  155. BN_mod_mul(tmp2,k,e,order,ctx);
  156. if (!s) s=BN_CTX_get(ctx);
  157. BN_mod_add(s,tmp,tmp2,order,ctx);
  158. }
  159. while (BN_is_zero(s));
  160. newsig->s=BN_dup(s);
  161. newsig->r=BN_dup(r);
  162. err:
  163. BN_CTX_end(ctx);
  164. BN_CTX_free(ctx);
  165. EC_POINT_free(C);
  166. BN_free(md);
  167. return newsig;
  168. }
  169. /*
  170. * Verifies gost 2001 signature
  171. *
  172. */
  173. int gost2001_do_verify(const unsigned char *dgst,int dgst_len,
  174. DSA_SIG *sig, EC_KEY *ec)
  175. {
  176. BN_CTX *ctx=BN_CTX_new();
  177. const EC_GROUP *group = EC_KEY_get0_group(ec);
  178. BIGNUM *order;
  179. BIGNUM *md = NULL,*e=NULL,*R=NULL,*v=NULL,*z1=NULL,*z2=NULL;
  180. BIGNUM *X=NULL,*tmp=NULL;
  181. EC_POINT *C = NULL;
  182. const EC_POINT *pub_key=NULL;
  183. int ok=0;
  184. BN_CTX_start(ctx);
  185. order = BN_CTX_get(ctx);
  186. e = BN_CTX_get(ctx);
  187. z1 = BN_CTX_get(ctx);
  188. z2 = BN_CTX_get(ctx);
  189. tmp = BN_CTX_get(ctx);
  190. X= BN_CTX_get(ctx);
  191. R=BN_CTX_get(ctx);
  192. v=BN_CTX_get(ctx);
  193. EC_GROUP_get_order(group,order,ctx);
  194. pub_key = EC_KEY_get0_public_key(ec);
  195. if (BN_is_zero(sig->s) || BN_is_zero(sig->r) ||
  196. (BN_cmp(sig->s,order)>=1) || (BN_cmp(sig->r,order)>=1))
  197. {
  198. GOSTerr(GOST_F_GOST2001_DO_VERIFY,GOST_R_SIGNATURE_PARTS_GREATER_THAN_Q);
  199. goto err;
  200. }
  201. md = hashsum2bn(dgst);
  202. BN_mod(e,md,order,ctx);
  203. #ifdef DEBUG_SIGN
  204. fprintf(stderr,"digest as bignum: ");
  205. BN_print_fp(stderr,md);
  206. fprintf(stderr,"\ndigest mod q: ");
  207. BN_print_fp(stderr,e);
  208. #endif
  209. if (BN_is_zero(e)) BN_one(e);
  210. v=BN_mod_inverse(v,e,order,ctx);
  211. BN_mod_mul(z1,sig->s,v,order,ctx);
  212. BN_sub(tmp,order,sig->r);
  213. BN_mod_mul(z2,tmp,v,order,ctx);
  214. #ifdef DEBUG_SIGN
  215. fprintf(stderr,"\nInverted digest value: ");
  216. BN_print_fp(stderr,v);
  217. fprintf(stderr,"\nz1: ");
  218. BN_print_fp(stderr,z1);
  219. fprintf(stderr,"\nz2: ");
  220. BN_print_fp(stderr,z2);
  221. #endif
  222. C = EC_POINT_new(group);
  223. if (!EC_POINT_mul(group,C,z1,pub_key,z2,ctx))
  224. {
  225. GOSTerr(GOST_F_GOST2001_DO_VERIFY,ERR_R_EC_LIB);
  226. goto err;
  227. }
  228. if (!EC_POINT_get_affine_coordinates_GFp(group,C,X,NULL,ctx))
  229. {
  230. GOSTerr(GOST_F_GOST2001_DO_VERIFY,ERR_R_EC_LIB);
  231. goto err;
  232. }
  233. BN_mod(R,X,order,ctx);
  234. #ifdef DEBUG_SIGN
  235. fprintf(stderr,"\nX=");
  236. BN_print_fp(stderr,X);
  237. fprintf(stderr,"\nX mod q=");
  238. BN_print_fp(stderr,R);
  239. fprintf(stderr,"\n");
  240. #endif
  241. if (BN_cmp(R,sig->r)!=0)
  242. {
  243. GOSTerr(GOST_F_GOST2001_DO_VERIFY,GOST_R_SIGNATURE_MISMATCH);
  244. }
  245. else
  246. {
  247. ok = 1;
  248. }
  249. err:
  250. EC_POINT_free(C);
  251. BN_CTX_end(ctx);
  252. BN_CTX_free(ctx);
  253. BN_free(md);
  254. return ok;
  255. }
  256. /*
  257. * Computes GOST R 34.10-2001 public key
  258. *
  259. *
  260. */
  261. int gost2001_compute_public(EC_KEY *ec)
  262. {
  263. const EC_GROUP *group = EC_KEY_get0_group(ec);
  264. EC_POINT *pub_key=NULL;
  265. const BIGNUM *priv_key=NULL;
  266. BN_CTX *ctx=NULL;
  267. int ok=0;
  268. if (!group)
  269. {
  270. GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC,GOST_R_KEY_IS_NOT_INITIALIZED);
  271. return 0;
  272. }
  273. ctx=BN_CTX_new();
  274. BN_CTX_start(ctx);
  275. if (!(priv_key=EC_KEY_get0_private_key(ec)))
  276. {
  277. GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC,ERR_R_EC_LIB);
  278. goto err;
  279. }
  280. pub_key = EC_POINT_new(group);
  281. if (!EC_POINT_mul(group,pub_key,priv_key,NULL,NULL,ctx))
  282. {
  283. GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC,ERR_R_EC_LIB);
  284. goto err;
  285. }
  286. if (!EC_KEY_set_public_key(ec,pub_key))
  287. {
  288. GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC,ERR_R_EC_LIB);
  289. goto err;
  290. }
  291. ok = 256;
  292. err:
  293. BN_CTX_end(ctx);
  294. EC_POINT_free(pub_key);
  295. BN_CTX_free(ctx);
  296. return ok;
  297. }
  298. /*
  299. *
  300. * Generates GOST R 34.10-2001 keypair
  301. *
  302. *
  303. */
  304. int gost2001_keygen(EC_KEY *ec)
  305. {
  306. BIGNUM *order = BN_new(),*d=BN_new();
  307. const EC_GROUP *group = EC_KEY_get0_group(ec);
  308. EC_GROUP_get_order(group,order,NULL);
  309. do
  310. {
  311. if (!BN_rand_range(d,order))
  312. {
  313. GOSTerr(GOST_F_GOST2001_KEYGEN,GOST_R_RANDOM_NUMBER_GENERATOR_FAILED);
  314. BN_free(d);
  315. BN_free(order);
  316. return 0;
  317. }
  318. }
  319. while (BN_is_zero(d));
  320. EC_KEY_set_private_key(ec,d);
  321. BN_free(d);
  322. BN_free(order);
  323. return gost2001_compute_public(ec);
  324. }