A local copy of OpenSSL from GitHub
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

84 lines
2.0 KiB

  1. /*
  2. * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
  3. *
  4. * Licensed under the OpenSSL license (the "License"). You may not use
  5. * this file except in compliance with the License. You can obtain a copy
  6. * in the file LICENSE in the source distribution or at
  7. * https://www.openssl.org/source/license.html
  8. */
  9. #include <stdio.h>
  10. #include <time.h>
  11. #include "internal/cryptlib.h"
  12. #include <openssl/bn.h>
  13. #include "dsa_locl.h"
  14. #include <openssl/rand.h>
  15. static int dsa_builtin_keygen(DSA *dsa);
  16. int DSA_generate_key(DSA *dsa)
  17. {
  18. if (dsa->meth->dsa_keygen)
  19. return dsa->meth->dsa_keygen(dsa);
  20. return dsa_builtin_keygen(dsa);
  21. }
  22. static int dsa_builtin_keygen(DSA *dsa)
  23. {
  24. int ok = 0;
  25. BN_CTX *ctx = NULL;
  26. BIGNUM *pub_key = NULL, *priv_key = NULL;
  27. if ((ctx = BN_CTX_new()) == NULL)
  28. goto err;
  29. if (dsa->priv_key == NULL) {
  30. if ((priv_key = BN_secure_new()) == NULL)
  31. goto err;
  32. } else
  33. priv_key = dsa->priv_key;
  34. do
  35. if (!BN_rand_range(priv_key, dsa->q))
  36. goto err;
  37. while (BN_is_zero(priv_key)) ;
  38. if (dsa->pub_key == NULL) {
  39. if ((pub_key = BN_new()) == NULL)
  40. goto err;
  41. } else
  42. pub_key = dsa->pub_key;
  43. {
  44. BIGNUM *local_prk = NULL;
  45. BIGNUM *prk;
  46. if ((dsa->flags & DSA_FLAG_NO_EXP_CONSTTIME) == 0) {
  47. local_prk = prk = BN_new();
  48. if (local_prk == NULL)
  49. goto err;
  50. BN_with_flags(prk, priv_key, BN_FLG_CONSTTIME);
  51. } else {
  52. prk = priv_key;
  53. }
  54. if (!BN_mod_exp(pub_key, dsa->g, prk, dsa->p, ctx)) {
  55. BN_free(local_prk);
  56. goto err;
  57. }
  58. /* We MUST free local_prk before any further use of priv_key */
  59. BN_free(local_prk);
  60. }
  61. dsa->priv_key = priv_key;
  62. dsa->pub_key = pub_key;
  63. ok = 1;
  64. err:
  65. if (pub_key != dsa->pub_key)
  66. BN_free(pub_key);
  67. if (priv_key != dsa->priv_key)
  68. BN_free(priv_key);
  69. BN_CTX_free(ctx);
  70. return (ok);
  71. }