PageRenderTime 51ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/MicroFrameworkPK_v4_2/DeviceCode/pal/OpenSSL/OpenSSL_1_0_0/engines/ccgost/gost_sign.cpp

https://github.com/pmfsampaio/NETMF-LPC
C++ | 321 lines | 222 code | 22 blank | 77 comment | 25 complexity | 4625a7f2b21242d9fa51c508600cac31 MD5 | raw file
  1. /**********************************************************************
  2. * gost_sign.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-94 signature algorithm *
  7. * for OpenSSL *
  8. * Requires OpenSSL 0.9.9 for compilation *
  9. **********************************************************************/
  10. #include <openssl/rand.h>
  11. #include <openssl/bn.h>
  12. #include <openssl/dsa.h>
  13. #include <openssl/evp.h>
  14. #include <string.h>
  15. #include "gost_params.h"
  16. #include "gost_lcl.h"
  17. #include "e_gost_err.h"
  18. #ifdef DEBUG_SIGN
  19. void dump_signature(const char *message,const unsigned char *buffer,size_t len)
  20. {
  21. size_t i;
  22. TINYCLR_SSL_FPRINTF(OPENSSL_TYPE__FILE_STDERR,"signature %s Length=%d",message,len);
  23. for (i=0; i<len; i++)
  24. {
  25. if (i% 16 ==0) TINYCLR_SSL_FPUTC('\n',OPENSSL_TYPE__FILE_STDERR);
  26. TINYCLR_SSL_FPRINTF (OPENSSL_TYPE__FILE_STDERR," %02x",buffer[i]);
  27. }
  28. TINYCLR_SSL_FPRINTF(OPENSSL_TYPE__FILE_STDERR,"\nEnd of signature\n");
  29. }
  30. void dump_dsa_sig(const char *message, DSA_SIG *sig)
  31. {
  32. TINYCLR_SSL_FPRINTF(OPENSSL_TYPE__FILE_STDERR,"%s\nR=",message);
  33. BN_print_fp(OPENSSL_TYPE__FILE_STDERR,sig->r);
  34. TINYCLR_SSL_FPRINTF(OPENSSL_TYPE__FILE_STDERR,"\nS=");
  35. BN_print_fp(OPENSSL_TYPE__FILE_STDERR,sig->s);
  36. TINYCLR_SSL_FPRINTF(OPENSSL_TYPE__FILE_STDERR,"\n");
  37. }
  38. #else
  39. #define dump_signature(a,b,c)
  40. #define dump_dsa_sig(a,b)
  41. #endif
  42. /*
  43. * Computes signature and returns it as DSA_SIG structure
  44. */
  45. DSA_SIG *gost_do_sign(const unsigned char *dgst,int dlen, DSA *dsa)
  46. {
  47. BIGNUM *k=NULL,*tmp=NULL,*tmp2=NULL;
  48. DSA_SIG *newsig = DSA_SIG_new();
  49. BIGNUM *md = hashsum2bn(dgst);
  50. /* check if H(M) mod q is zero */
  51. BN_CTX *ctx=BN_CTX_new();
  52. BN_CTX_start(ctx);
  53. if (!newsig)
  54. {
  55. GOSTerr(GOST_F_GOST_DO_SIGN,GOST_R_NO_MEMORY);
  56. goto err;
  57. }
  58. tmp=BN_CTX_get(ctx);
  59. k = BN_CTX_get(ctx);
  60. tmp2 = BN_CTX_get(ctx);
  61. BN_mod(tmp,md,dsa->q,ctx);
  62. if (BN_is_zero(tmp))
  63. {
  64. BN_one(md);
  65. }
  66. do
  67. {
  68. do
  69. {
  70. /*Generate random number k less than q*/
  71. BN_rand_range(k,dsa->q);
  72. /* generate r = (a^x mod p) mod q */
  73. BN_mod_exp(tmp,dsa->g, k, dsa->p,ctx);
  74. if (!(newsig->r)) newsig->r=BN_new();
  75. BN_mod(newsig->r,tmp,dsa->q,ctx);
  76. }
  77. while (BN_is_zero(newsig->r));
  78. /* generate s = (xr + k(Hm)) mod q */
  79. BN_mod_mul(tmp,dsa->priv_key,newsig->r,dsa->q,ctx);
  80. BN_mod_mul(tmp2,k,md,dsa->q,ctx);
  81. if (!newsig->s) newsig->s=BN_new();
  82. BN_mod_add(newsig->s,tmp,tmp2,dsa->q,ctx);
  83. }
  84. while (BN_is_zero(newsig->s));
  85. err:
  86. BN_free(md);
  87. BN_CTX_end(ctx);
  88. BN_CTX_free(ctx);
  89. return newsig;
  90. }
  91. /*
  92. * Packs signature according to Cryptocom rules
  93. * and frees up DSA_SIG structure
  94. */
  95. /*
  96. int pack_sign_cc(DSA_SIG *s,int order,unsigned char *sig, size_t *siglen)
  97. {
  98. *siglen = 2*order;
  99. TINYCLR_SSL_MEMSET(sig,0,*siglen);
  100. store_bignum(s->r, sig,order);
  101. store_bignum(s->s, sig + order,order);
  102. dump_signature("serialized",sig,*siglen);
  103. DSA_SIG_free(s);
  104. return 1;
  105. }
  106. */
  107. /*
  108. * Packs signature according to Cryptopro rules
  109. * and frees up DSA_SIG structure
  110. */
  111. int pack_sign_cp(DSA_SIG *s,int order,unsigned char *sig, size_t *siglen)
  112. {
  113. *siglen = 2*order;
  114. TINYCLR_SSL_MEMSET(sig,0,*siglen);
  115. store_bignum(s->s, sig, order);
  116. store_bignum(s->r, sig+order,order);
  117. dump_signature("serialized",sig,*siglen);
  118. DSA_SIG_free(s);
  119. return 1;
  120. }
  121. /*
  122. * Verifies signature passed as DSA_SIG structure
  123. *
  124. */
  125. int gost_do_verify(const unsigned char *dgst, int dgst_len,
  126. DSA_SIG *sig, DSA *dsa)
  127. {
  128. BIGNUM *md, *tmp=NULL;
  129. BIGNUM *q2=NULL;
  130. BIGNUM *u=NULL,*v=NULL,*z1=NULL,*z2=NULL;
  131. BIGNUM *tmp2=NULL,*tmp3=NULL;
  132. int ok;
  133. BN_CTX *ctx = BN_CTX_new();
  134. BN_CTX_start(ctx);
  135. if (BN_cmp(sig->s,dsa->q)>=1||
  136. BN_cmp(sig->r,dsa->q)>=1)
  137. {
  138. GOSTerr(GOST_F_GOST_DO_VERIFY,GOST_R_SIGNATURE_PARTS_GREATER_THAN_Q);
  139. return 0;
  140. }
  141. md=hashsum2bn(dgst);
  142. tmp=BN_CTX_get(ctx);
  143. v=BN_CTX_get(ctx);
  144. q2=BN_CTX_get(ctx);
  145. z1=BN_CTX_get(ctx);
  146. z2=BN_CTX_get(ctx);
  147. tmp2=BN_CTX_get(ctx);
  148. tmp3=BN_CTX_get(ctx);
  149. u = BN_CTX_get(ctx);
  150. BN_mod(tmp,md,dsa->q,ctx);
  151. if (BN_is_zero(tmp))
  152. {
  153. BN_one(md);
  154. }
  155. BN_copy(q2,dsa->q);
  156. BN_sub_word(q2,2);
  157. BN_mod_exp(v,md,q2,dsa->q,ctx);
  158. BN_mod_mul(z1,sig->s,v,dsa->q,ctx);
  159. BN_sub(tmp,dsa->q,sig->r);
  160. BN_mod_mul(z2,tmp,v,dsa->p,ctx);
  161. BN_mod_exp(tmp,dsa->g,z1,dsa->p,ctx);
  162. BN_mod_exp(tmp2,dsa->pub_key,z2,dsa->p,ctx);
  163. BN_mod_mul(tmp3,tmp,tmp2,dsa->p,ctx);
  164. BN_mod(u,tmp3,dsa->q,ctx);
  165. ok= BN_cmp(u,sig->r);
  166. BN_free(md);
  167. BN_CTX_end(ctx);
  168. BN_CTX_free(ctx);
  169. if (ok!=0)
  170. {
  171. GOSTerr(GOST_F_GOST_DO_VERIFY,GOST_R_SIGNATURE_MISMATCH);
  172. }
  173. return (ok==0);
  174. }
  175. /*
  176. * Computes public keys for GOST R 34.10-94 algorithm
  177. *
  178. */
  179. int gost94_compute_public(DSA *dsa)
  180. {
  181. /* Now fill algorithm parameters with correct values */
  182. BN_CTX *ctx = BN_CTX_new();
  183. if (!dsa->g)
  184. {
  185. GOSTerr(GOST_F_GOST94_COMPUTE_PUBLIC,GOST_R_KEY_IS_NOT_INITALIZED);
  186. return 0;
  187. }
  188. /* Compute public key y = a^x mod p */
  189. dsa->pub_key=BN_new();
  190. BN_mod_exp(dsa->pub_key, dsa->g,dsa->priv_key,dsa->p,ctx);
  191. BN_CTX_free(ctx);
  192. return 1;
  193. }
  194. /*
  195. * Fill GOST 94 params, searching them in R3410_paramset array
  196. * by nid of paramset
  197. *
  198. */
  199. int fill_GOST94_params(DSA *dsa,int nid)
  200. {
  201. R3410_params *params=R3410_paramset;
  202. while (params->nid!=NID_undef && params->nid !=nid) params++;
  203. if (params->nid == NID_undef)
  204. {
  205. GOSTerr(GOST_F_FILL_GOST94_PARAMS,GOST_R_UNSUPPORTED_PARAMETER_SET);
  206. return 0;
  207. }
  208. #define dump_signature(a,b,c)
  209. if (dsa->p) { BN_free(dsa->p); }
  210. dsa->p=NULL;
  211. BN_dec2bn(&(dsa->p),params->p);
  212. if (dsa->q) { BN_free(dsa->q); }
  213. dsa->q=NULL;
  214. BN_dec2bn(&(dsa->q),params->q);
  215. if (dsa->g) { BN_free(dsa->g); }
  216. dsa->g=NULL;
  217. BN_dec2bn(&(dsa->g),params->a);
  218. return 1;
  219. }
  220. /*
  221. * Generate GOST R 34.10-94 keypair
  222. *
  223. *
  224. */
  225. int gost_sign_keygen(DSA *dsa)
  226. {
  227. dsa->priv_key = BN_new();
  228. BN_rand_range(dsa->priv_key,dsa->q);
  229. return gost94_compute_public( dsa);
  230. }
  231. /* Unpack signature according to cryptocom rules */
  232. /*
  233. DSA_SIG *unpack_cc_signature(const unsigned char *sig,size_t siglen)
  234. {
  235. DSA_SIG *s;
  236. s = DSA_SIG_new();
  237. if (s == NULL)
  238. {
  239. GOSTerr(GOST_F_UNPACK_CC_SIGNATURE,GOST_R_NO_MEMORY);
  240. return(NULL);
  241. }
  242. s->r = getbnfrombuf(sig, siglen/2);
  243. s->s = getbnfrombuf(sig + siglen/2, siglen/2);
  244. return s;
  245. }
  246. */
  247. /* Unpack signature according to cryptopro rules */
  248. DSA_SIG *unpack_cp_signature(const unsigned char *sig,size_t siglen)
  249. {
  250. DSA_SIG *s;
  251. s = DSA_SIG_new();
  252. if (s == NULL)
  253. {
  254. GOSTerr(GOST_F_UNPACK_CP_SIGNATURE,GOST_R_NO_MEMORY);
  255. return NULL;
  256. }
  257. s->s = getbnfrombuf(sig , siglen/2);
  258. s->r = getbnfrombuf(sig + siglen/2, siglen/2);
  259. return s;
  260. }
  261. /* Convert little-endian byte array into bignum */
  262. BIGNUM *hashsum2bn(const unsigned char *dgst)
  263. {
  264. unsigned char buf[32];
  265. int i;
  266. for (i=0;i<32;i++)
  267. {
  268. buf[31-i]=dgst[i];
  269. }
  270. return getbnfrombuf(buf,32);
  271. }
  272. /* Convert byte buffer to bignum, skipping leading zeros*/
  273. BIGNUM *getbnfrombuf(const unsigned char *buf,size_t len)
  274. {
  275. while (*buf==0&&len>0)
  276. {
  277. buf++; len--;
  278. }
  279. if (len)
  280. {
  281. return BN_bin2bn(buf,len,NULL);
  282. }
  283. else
  284. {
  285. BIGNUM *b=BN_new();
  286. BN_zero(b);
  287. return b;
  288. }
  289. }
  290. /* Pack bignum into byte buffer of given size, filling all leading bytes
  291. * by zeros */
  292. int store_bignum(BIGNUM *bn, unsigned char *buf,int len)
  293. {
  294. int bytes = BN_num_bytes(bn);
  295. if (bytes>len) return 0;
  296. TINYCLR_SSL_MEMSET(buf,0,len);
  297. BN_bn2bin(bn,buf+len-bytes);
  298. return 1;
  299. }