fips_dsa_ossl.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452
  1. /* crypto/dsa/dsa_ossl.c */
  2. /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  3. * All rights reserved.
  4. *
  5. * This package is an SSL implementation written
  6. * by Eric Young (eay@cryptsoft.com).
  7. * The implementation was written so as to conform with Netscapes SSL.
  8. *
  9. * This library is free for commercial and non-commercial use as long as
  10. * the following conditions are aheared to. The following conditions
  11. * apply to all code found in this distribution, be it the RC4, RSA,
  12. * lhash, DES, etc., code; not just the SSL code. The SSL documentation
  13. * included with this distribution is covered by the same copyright terms
  14. * except that the holder is Tim Hudson (tjh@cryptsoft.com).
  15. *
  16. * Copyright remains Eric Young's, and as such any Copyright notices in
  17. * the code are not to be removed.
  18. * If this package is used in a product, Eric Young should be given attribution
  19. * as the author of the parts of the library used.
  20. * This can be in the form of a textual message at program startup or
  21. * in documentation (online or textual) provided with the package.
  22. *
  23. * Redistribution and use in source and binary forms, with or without
  24. * modification, are permitted provided that the following conditions
  25. * are met:
  26. * 1. Redistributions of source code must retain the copyright
  27. * notice, this list of conditions and the following disclaimer.
  28. * 2. Redistributions in binary form must reproduce the above copyright
  29. * notice, this list of conditions and the following disclaimer in the
  30. * documentation and/or other materials provided with the distribution.
  31. * 3. All advertising materials mentioning features or use of this software
  32. * must display the following acknowledgement:
  33. * "This product includes cryptographic software written by
  34. * Eric Young (eay@cryptsoft.com)"
  35. * The word 'cryptographic' can be left out if the rouines from the library
  36. * being used are not cryptographic related :-).
  37. * 4. If you include any Windows specific code (or a derivative thereof) from
  38. * the apps directory (application code) you must include an acknowledgement:
  39. * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
  40. *
  41. * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
  42. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  43. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  44. * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  45. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  46. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  47. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  48. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  49. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  50. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  51. * SUCH DAMAGE.
  52. *
  53. * The licence and distribution terms for any publically available version or
  54. * derivative of this code cannot be changed. i.e. this code cannot simply be
  55. * copied and put under another distribution licence
  56. * [including the GNU Public Licence.]
  57. */
  58. /* Original version from Steven Schoch <schoch@sheba.arc.nasa.gov> */
  59. #include <stdio.h>
  60. #include <openssl/bn.h>
  61. #include <openssl/dsa.h>
  62. #include <openssl/rand.h>
  63. #include <openssl/asn1.h>
  64. #include <openssl/err.h>
  65. #ifndef OPENSSL_NO_ENGINE
  66. # include <openssl/engine.h>
  67. #endif
  68. #include <openssl/fips.h>
  69. #ifdef OPENSSL_FIPS
  70. static DSA_SIG *dsa_do_sign(const unsigned char *dgst, FIPS_DSA_SIZE_T dlen,
  71. DSA *dsa);
  72. static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp,
  73. BIGNUM **rp);
  74. static int dsa_do_verify(const unsigned char *dgst, FIPS_DSA_SIZE_T dgst_len,
  75. DSA_SIG *sig, DSA *dsa);
  76. static int dsa_init(DSA *dsa);
  77. static int dsa_finish(DSA *dsa);
  78. static int dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1, BIGNUM *p1,
  79. BIGNUM *a2, BIGNUM *p2, BIGNUM *m, BN_CTX *ctx,
  80. BN_MONT_CTX *in_mont);
  81. static int dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a, const BIGNUM *p,
  82. const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
  83. static const DSA_METHOD openssl_dsa_meth = {
  84. "OpenSSL FIPS DSA method",
  85. dsa_do_sign,
  86. dsa_sign_setup,
  87. dsa_do_verify,
  88. dsa_mod_exp,
  89. dsa_bn_mod_exp,
  90. dsa_init,
  91. dsa_finish,
  92. DSA_FLAG_FIPS_METHOD,
  93. NULL
  94. };
  95. # if 0
  96. int FIPS_dsa_check(struct dsa_st *dsa)
  97. {
  98. if (dsa->meth != &openssl_dsa_meth
  99. || dsa->meth->dsa_do_sign != dsa_do_sign
  100. || dsa->meth->dsa_sign_setup != dsa_sign_setup
  101. || dsa->meth->dsa_mod_exp != dsa_mod_exp
  102. || dsa->meth->bn_mod_exp != dsa_bn_mod_exp
  103. || dsa->meth->init != dsa_init || dsa->meth->finish != dsa_finish) {
  104. FIPSerr(FIPS_F_FIPS_DSA_CHECK, FIPS_R_NON_FIPS_METHOD);
  105. return 0;
  106. }
  107. return 1;
  108. }
  109. # endif
  110. const DSA_METHOD *DSA_OpenSSL(void)
  111. {
  112. return &openssl_dsa_meth;
  113. }
  114. static DSA_SIG *dsa_do_sign(const unsigned char *dgst, FIPS_DSA_SIZE_T dlen,
  115. DSA *dsa)
  116. {
  117. BIGNUM *kinv = NULL, *r = NULL, *s = NULL;
  118. BIGNUM m;
  119. BIGNUM xr;
  120. BN_CTX *ctx = NULL;
  121. int i, reason = ERR_R_BN_LIB;
  122. DSA_SIG *ret = NULL;
  123. if (FIPS_selftest_failed()) {
  124. FIPSerr(FIPS_F_DSA_DO_SIGN, FIPS_R_FIPS_SELFTEST_FAILED);
  125. return NULL;
  126. }
  127. if (FIPS_mode()
  128. && (BN_num_bits(dsa->p) < OPENSSL_DSA_FIPS_MIN_MODULUS_BITS)) {
  129. DSAerr(DSA_F_DSA_DO_SIGN, DSA_R_KEY_SIZE_TOO_SMALL);
  130. return NULL;
  131. }
  132. BN_init(&m);
  133. BN_init(&xr);
  134. if (!dsa->p || !dsa->q || !dsa->g) {
  135. reason = DSA_R_MISSING_PARAMETERS;
  136. goto err;
  137. }
  138. s = BN_new();
  139. if (s == NULL)
  140. goto err;
  141. i = BN_num_bytes(dsa->q); /* should be 20 */
  142. if ((dlen > i) || (dlen > 50)) {
  143. reason = DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE;
  144. goto err;
  145. }
  146. ctx = BN_CTX_new();
  147. if (ctx == NULL)
  148. goto err;
  149. if (!dsa->meth->dsa_sign_setup(dsa, ctx, &kinv, &r))
  150. goto err;
  151. if (BN_bin2bn(dgst, dlen, &m) == NULL)
  152. goto err;
  153. /* Compute s = inv(k) (m + xr) mod q */
  154. if (!BN_mod_mul(&xr, dsa->priv_key, r, dsa->q, ctx))
  155. goto err; /* s = xr */
  156. if (!BN_add(s, &xr, &m))
  157. goto err; /* s = m + xr */
  158. if (BN_cmp(s, dsa->q) > 0)
  159. BN_sub(s, s, dsa->q);
  160. if (!BN_mod_mul(s, s, kinv, dsa->q, ctx))
  161. goto err;
  162. ret = DSA_SIG_new();
  163. if (ret == NULL)
  164. goto err;
  165. ret->r = r;
  166. ret->s = s;
  167. err:
  168. if (!ret) {
  169. DSAerr(DSA_F_DSA_DO_SIGN, reason);
  170. BN_free(r);
  171. BN_free(s);
  172. }
  173. if (ctx != NULL)
  174. BN_CTX_free(ctx);
  175. BN_clear_free(&m);
  176. BN_clear_free(&xr);
  177. if (kinv != NULL) /* dsa->kinv is NULL now if we used it */
  178. BN_clear_free(kinv);
  179. return (ret);
  180. }
  181. static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp,
  182. BIGNUM **rp)
  183. {
  184. BN_CTX *ctx;
  185. BIGNUM k, kq, *K, *kinv = NULL, *r = NULL;
  186. int ret = 0;
  187. if (!dsa->p || !dsa->q || !dsa->g) {
  188. DSAerr(DSA_F_DSA_SIGN_SETUP, DSA_R_MISSING_PARAMETERS);
  189. return 0;
  190. }
  191. BN_init(&k);
  192. BN_init(&kq);
  193. if (ctx_in == NULL) {
  194. if ((ctx = BN_CTX_new()) == NULL)
  195. goto err;
  196. } else
  197. ctx = ctx_in;
  198. if ((r = BN_new()) == NULL)
  199. goto err;
  200. /* Get random k */
  201. do
  202. if (!BN_rand_range(&k, dsa->q))
  203. goto err;
  204. while (BN_is_zero(&k)) ;
  205. if ((dsa->flags & DSA_FLAG_NO_EXP_CONSTTIME) == 0) {
  206. BN_set_flags(&k, BN_FLG_CONSTTIME);
  207. }
  208. if (dsa->flags & DSA_FLAG_CACHE_MONT_P) {
  209. if (!BN_MONT_CTX_set_locked((BN_MONT_CTX **)&dsa->method_mont_p,
  210. CRYPTO_LOCK_DSA, dsa->p, ctx))
  211. goto err;
  212. }
  213. /* Compute r = (g^k mod p) mod q */
  214. if ((dsa->flags & DSA_FLAG_NO_EXP_CONSTTIME) == 0) {
  215. if (!BN_copy(&kq, &k))
  216. goto err;
  217. /*
  218. * We do not want timing information to leak the length of k, so we
  219. * compute g^k using an equivalent exponent of fixed length. (This
  220. * is a kludge that we need because the BN_mod_exp_mont() does not
  221. * let us specify the desired timing behaviour.)
  222. */
  223. if (!BN_add(&kq, &kq, dsa->q))
  224. goto err;
  225. if (BN_num_bits(&kq) <= BN_num_bits(dsa->q)) {
  226. if (!BN_add(&kq, &kq, dsa->q))
  227. goto err;
  228. }
  229. K = &kq;
  230. } else {
  231. K = &k;
  232. }
  233. if (!dsa->meth->bn_mod_exp(dsa, r, dsa->g, K, dsa->p, ctx,
  234. (BN_MONT_CTX *)dsa->method_mont_p))
  235. goto err;
  236. if (!BN_mod(r, r, dsa->q, ctx))
  237. goto err;
  238. /* Compute part of 's = inv(k) (m + xr) mod q' */
  239. if ((kinv = BN_mod_inverse(NULL, &k, dsa->q, ctx)) == NULL)
  240. goto err;
  241. if (*kinvp != NULL)
  242. BN_clear_free(*kinvp);
  243. *kinvp = kinv;
  244. kinv = NULL;
  245. if (*rp != NULL)
  246. BN_clear_free(*rp);
  247. *rp = r;
  248. ret = 1;
  249. err:
  250. if (!ret) {
  251. DSAerr(DSA_F_DSA_SIGN_SETUP, ERR_R_BN_LIB);
  252. if (kinv != NULL)
  253. BN_clear_free(kinv);
  254. if (r != NULL)
  255. BN_clear_free(r);
  256. }
  257. if (ctx_in == NULL)
  258. BN_CTX_free(ctx);
  259. if (kinv != NULL)
  260. BN_clear_free(kinv);
  261. BN_clear_free(&k);
  262. BN_clear_free(&kq);
  263. return (ret);
  264. }
  265. static int dsa_do_verify(const unsigned char *dgst, FIPS_DSA_SIZE_T dgst_len,
  266. DSA_SIG *sig, DSA *dsa)
  267. {
  268. BN_CTX *ctx;
  269. BIGNUM u1, u2, t1;
  270. BN_MONT_CTX *mont = NULL;
  271. int ret = -1;
  272. if (!dsa->p || !dsa->q || !dsa->g) {
  273. DSAerr(DSA_F_DSA_DO_VERIFY, DSA_R_MISSING_PARAMETERS);
  274. return -1;
  275. }
  276. if (FIPS_selftest_failed()) {
  277. FIPSerr(FIPS_F_DSA_DO_VERIFY, FIPS_R_FIPS_SELFTEST_FAILED);
  278. return -1;
  279. }
  280. if (BN_num_bits(dsa->q) != 160) {
  281. DSAerr(DSA_F_DSA_DO_VERIFY, DSA_R_BAD_Q_VALUE);
  282. return -1;
  283. }
  284. if (BN_num_bits(dsa->p) > OPENSSL_DSA_MAX_MODULUS_BITS) {
  285. DSAerr(DSA_F_DSA_DO_VERIFY, DSA_R_MODULUS_TOO_LARGE);
  286. return -1;
  287. }
  288. if (FIPS_mode()
  289. && (BN_num_bits(dsa->p) < OPENSSL_DSA_FIPS_MIN_MODULUS_BITS)) {
  290. DSAerr(DSA_F_DSA_DO_VERIFY, DSA_R_KEY_SIZE_TOO_SMALL);
  291. return -1;
  292. }
  293. BN_init(&u1);
  294. BN_init(&u2);
  295. BN_init(&t1);
  296. if ((ctx = BN_CTX_new()) == NULL)
  297. goto err;
  298. if (BN_is_zero(sig->r) || sig->r->neg || BN_ucmp(sig->r, dsa->q) >= 0) {
  299. ret = 0;
  300. goto err;
  301. }
  302. if (BN_is_zero(sig->s) || sig->s->neg || BN_ucmp(sig->s, dsa->q) >= 0) {
  303. ret = 0;
  304. goto err;
  305. }
  306. /*
  307. * Calculate W = inv(S) mod Q save W in u2
  308. */
  309. if ((BN_mod_inverse(&u2, sig->s, dsa->q, ctx)) == NULL)
  310. goto err;
  311. /* save M in u1 */
  312. if (BN_bin2bn(dgst, dgst_len, &u1) == NULL)
  313. goto err;
  314. /* u1 = M * w mod q */
  315. if (!BN_mod_mul(&u1, &u1, &u2, dsa->q, ctx))
  316. goto err;
  317. /* u2 = r * w mod q */
  318. if (!BN_mod_mul(&u2, sig->r, &u2, dsa->q, ctx))
  319. goto err;
  320. if (dsa->flags & DSA_FLAG_CACHE_MONT_P) {
  321. mont = BN_MONT_CTX_set_locked((BN_MONT_CTX **)&dsa->method_mont_p,
  322. CRYPTO_LOCK_DSA, dsa->p, ctx);
  323. if (!mont)
  324. goto err;
  325. }
  326. # if 0
  327. {
  328. BIGNUM t2;
  329. BN_init(&t2);
  330. /* v = ( g^u1 * y^u2 mod p ) mod q */
  331. /* let t1 = g ^ u1 mod p */
  332. if (!BN_mod_exp_mont(&t1, dsa->g, &u1, dsa->p, ctx, mont))
  333. goto err;
  334. /* let t2 = y ^ u2 mod p */
  335. if (!BN_mod_exp_mont(&t2, dsa->pub_key, &u2, dsa->p, ctx, mont))
  336. goto err;
  337. /* let u1 = t1 * t2 mod p */
  338. if (!BN_mod_mul(&u1, &t1, &t2, dsa->p, ctx))
  339. goto err_bn;
  340. BN_free(&t2);
  341. }
  342. /* let u1 = u1 mod q */
  343. if (!BN_mod(&u1, &u1, dsa->q, ctx))
  344. goto err;
  345. # else
  346. {
  347. if (!dsa->meth->dsa_mod_exp(dsa, &t1, dsa->g, &u1, dsa->pub_key, &u2,
  348. dsa->p, ctx, mont))
  349. goto err;
  350. /* BN_copy(&u1,&t1); */
  351. /* let u1 = u1 mod q */
  352. if (!BN_mod(&u1, &t1, dsa->q, ctx))
  353. goto err;
  354. }
  355. # endif
  356. /*
  357. * V is now in u1. If the signature is correct, it will be equal to R.
  358. */
  359. ret = (BN_ucmp(&u1, sig->r) == 0);
  360. err:
  361. if (ret != 1)
  362. DSAerr(DSA_F_DSA_DO_VERIFY, ERR_R_BN_LIB);
  363. if (ctx != NULL)
  364. BN_CTX_free(ctx);
  365. BN_free(&u1);
  366. BN_free(&u2);
  367. BN_free(&t1);
  368. return (ret);
  369. }
  370. static int dsa_init(DSA *dsa)
  371. {
  372. FIPS_selftest_check();
  373. dsa->flags |= DSA_FLAG_CACHE_MONT_P;
  374. return (1);
  375. }
  376. static int dsa_finish(DSA *dsa)
  377. {
  378. if (dsa->method_mont_p)
  379. BN_MONT_CTX_free((BN_MONT_CTX *)dsa->method_mont_p);
  380. return (1);
  381. }
  382. static int dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1, BIGNUM *p1,
  383. BIGNUM *a2, BIGNUM *p2, BIGNUM *m, BN_CTX *ctx,
  384. BN_MONT_CTX *in_mont)
  385. {
  386. return BN_mod_exp2_mont(rr, a1, p1, a2, p2, m, ctx, in_mont);
  387. }
  388. static int dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a, const BIGNUM *p,
  389. const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
  390. {
  391. return BN_mod_exp_mont(r, a, p, m, ctx, m_ctx);
  392. }
  393. #else /* ndef OPENSSL_FIPS */
  394. static void *dummy = &dummy;
  395. #endif /* ndef OPENSSL_FIPS */