gost2001.c 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340
  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. goto err;
  130. }
  131. if (!EC_POINT_mul(group,C,k,NULL,NULL,ctx))
  132. {
  133. GOSTerr(GOST_F_GOST2001_DO_SIGN,ERR_R_EC_LIB);
  134. DSA_SIG_free(newsig);
  135. goto err;
  136. }
  137. if (!X) X=BN_CTX_get(ctx);
  138. if (!EC_POINT_get_affine_coordinates_GFp(group,C,X,NULL,ctx))
  139. {
  140. GOSTerr(GOST_F_GOST2001_DO_SIGN,ERR_R_EC_LIB);
  141. DSA_SIG_free(newsig);
  142. goto err;
  143. }
  144. if (!r) r=BN_CTX_get(ctx);
  145. BN_nnmod(r,X,order,ctx);
  146. }
  147. while (BN_is_zero(r));
  148. /* s = (r*priv_key+k*e) mod order */
  149. if (!tmp) tmp = BN_CTX_get(ctx);
  150. BN_mod_mul(tmp,priv_key,r,order,ctx);
  151. if (!tmp2) tmp2 = BN_CTX_get(ctx);
  152. BN_mod_mul(tmp2,k,e,order,ctx);
  153. if (!s) s=BN_CTX_get(ctx);
  154. BN_mod_add(s,tmp,tmp2,order,ctx);
  155. }
  156. while (BN_is_zero(s));
  157. newsig->s=BN_dup(s);
  158. newsig->r=BN_dup(r);
  159. err:
  160. BN_CTX_end(ctx);
  161. BN_CTX_free(ctx);
  162. EC_POINT_free(C);
  163. BN_free(md);
  164. return newsig;
  165. }
  166. /*
  167. * Verifies gost 2001 signature
  168. *
  169. */
  170. int gost2001_do_verify(const unsigned char *dgst,int dgst_len,
  171. DSA_SIG *sig, EC_KEY *ec)
  172. {
  173. BN_CTX *ctx=BN_CTX_new();
  174. const EC_GROUP *group = EC_KEY_get0_group(ec);
  175. BIGNUM *order;
  176. BIGNUM *md = NULL,*e=NULL,*R=NULL,*v=NULL,*z1=NULL,*z2=NULL;
  177. BIGNUM *X=NULL,*tmp=NULL;
  178. EC_POINT *C = NULL;
  179. const EC_POINT *pub_key=NULL;
  180. int ok=0;
  181. BN_CTX_start(ctx);
  182. order = BN_CTX_get(ctx);
  183. e = BN_CTX_get(ctx);
  184. z1 = BN_CTX_get(ctx);
  185. z2 = BN_CTX_get(ctx);
  186. tmp = BN_CTX_get(ctx);
  187. X= BN_CTX_get(ctx);
  188. R=BN_CTX_get(ctx);
  189. v=BN_CTX_get(ctx);
  190. EC_GROUP_get_order(group,order,ctx);
  191. pub_key = EC_KEY_get0_public_key(ec);
  192. if (BN_is_zero(sig->s) || BN_is_zero(sig->r) ||
  193. (BN_cmp(sig->s,order)>=1) || (BN_cmp(sig->r,order)>=1))
  194. {
  195. GOSTerr(GOST_F_GOST2001_DO_VERIFY,GOST_R_SIGNATURE_PARTS_GREATER_THAN_Q);
  196. goto err;
  197. }
  198. md = hashsum2bn(dgst);
  199. BN_mod(e,md,order,ctx);
  200. #ifdef DEBUG_SIGN
  201. fprintf(stderr,"digest as bignum: ");
  202. BN_print_fp(stderr,md);
  203. fprintf(stderr,"\ndigest mod q: ");
  204. BN_print_fp(stderr,e);
  205. #endif
  206. if (BN_is_zero(e)) BN_one(e);
  207. v=BN_mod_inverse(v,e,order,ctx);
  208. BN_mod_mul(z1,sig->s,v,order,ctx);
  209. BN_sub(tmp,order,sig->r);
  210. BN_mod_mul(z2,tmp,v,order,ctx);
  211. #ifdef DEBUG_SIGN
  212. fprintf(stderr,"\nInverted digest value: ");
  213. BN_print_fp(stderr,v);
  214. fprintf(stderr,"\nz1: ");
  215. BN_print_fp(stderr,z1);
  216. fprintf(stderr,"\nz2: ");
  217. BN_print_fp(stderr,z2);
  218. #endif
  219. C = EC_POINT_new(group);
  220. if (!EC_POINT_mul(group,C,z1,pub_key,z2,ctx))
  221. {
  222. GOSTerr(GOST_F_GOST2001_DO_VERIFY,ERR_R_EC_LIB);
  223. goto err;
  224. }
  225. if (!EC_POINT_get_affine_coordinates_GFp(group,C,X,NULL,ctx))
  226. {
  227. GOSTerr(GOST_F_GOST2001_DO_VERIFY,ERR_R_EC_LIB);
  228. goto err;
  229. }
  230. BN_mod(R,X,order,ctx);
  231. #ifdef DEBUG_SIGN
  232. fprintf(stderr,"\nX=");
  233. BN_print_fp(stderr,X);
  234. fprintf(stderr,"\nX mod q=");
  235. BN_print_fp(stderr,R);
  236. fprintf(stderr,"\n");
  237. #endif
  238. if (BN_cmp(R,sig->r)!=0)
  239. {
  240. GOSTerr(GOST_F_GOST2001_DO_VERIFY,GOST_R_SIGNATURE_MISMATCH);
  241. }
  242. else
  243. {
  244. ok = 1;
  245. }
  246. err:
  247. EC_POINT_free(C);
  248. BN_CTX_end(ctx);
  249. BN_CTX_free(ctx);
  250. BN_free(md);
  251. return ok;
  252. }
  253. /*
  254. * Computes GOST R 34.10-2001 public key
  255. *
  256. *
  257. */
  258. int gost2001_compute_public(EC_KEY *ec)
  259. {
  260. const EC_GROUP *group = EC_KEY_get0_group(ec);
  261. EC_POINT *pub_key=NULL;
  262. const BIGNUM *priv_key=NULL;
  263. BN_CTX *ctx=NULL;
  264. int ok=0;
  265. if (!group)
  266. {
  267. GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC,GOST_R_KEY_IS_NOT_INITIALIZED);
  268. return 0;
  269. }
  270. ctx=BN_CTX_new();
  271. BN_CTX_start(ctx);
  272. if (!(priv_key=EC_KEY_get0_private_key(ec)))
  273. {
  274. GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC,ERR_R_EC_LIB);
  275. goto err;
  276. }
  277. pub_key = EC_POINT_new(group);
  278. if (!EC_POINT_mul(group,pub_key,priv_key,NULL,NULL,ctx))
  279. {
  280. GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC,ERR_R_EC_LIB);
  281. goto err;
  282. }
  283. if (!EC_KEY_set_public_key(ec,pub_key))
  284. {
  285. GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC,ERR_R_EC_LIB);
  286. goto err;
  287. }
  288. ok = 256;
  289. err:
  290. BN_CTX_end(ctx);
  291. EC_POINT_free(pub_key);
  292. BN_CTX_free(ctx);
  293. return ok;
  294. }
  295. /*
  296. *
  297. * Generates GOST R 34.10-2001 keypair
  298. *
  299. *
  300. */
  301. int gost2001_keygen(EC_KEY *ec)
  302. {
  303. BIGNUM *order = BN_new(),*d=BN_new();
  304. const EC_GROUP *group = EC_KEY_get0_group(ec);
  305. EC_GROUP_get_order(group,order,NULL);
  306. do
  307. {
  308. if (!BN_rand_range(d,order))
  309. {
  310. GOSTerr(GOST_F_GOST2001_KEYGEN,GOST_R_RANDOM_NUMBER_GENERATOR_FAILED);
  311. BN_free(d);
  312. BN_free(order);
  313. return 0;
  314. }
  315. }
  316. while (BN_is_zero(d));
  317. EC_KEY_set_private_key(ec,d);
  318. BN_free(d);
  319. BN_free(order);
  320. return gost2001_compute_public(ec);
  321. }