ffc_dh.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. /*
  2. * Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved.
  3. *
  4. * Licensed under the Apache License 2.0 (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 "internal/ffc.h"
  10. #include "internal/nelem.h"
  11. #include "crypto/bn_dh.h"
  12. #include "../bn/bn_local.h" // WINSCP
  13. #ifndef OPENSSL_NO_DH
  14. # define FFDHE(sz, keylength) { \
  15. SN_ffdhe##sz, NID_ffdhe##sz, \
  16. sz, \
  17. keylength, \
  18. &ossl_bignum_ffdhe##sz##_p, &ossl_bignum_ffdhe##sz##_q, \
  19. &ossl_bignum_const_2, \
  20. }
  21. # define MODP(sz, keylength) { \
  22. SN_modp_##sz, NID_modp_##sz, \
  23. sz, \
  24. keylength, \
  25. &ossl_bignum_modp_##sz##_p, &ossl_bignum_modp_##sz##_q, \
  26. &ossl_bignum_const_2 \
  27. }
  28. # define RFC5114(name, uid, sz, tag) { \
  29. name, uid, \
  30. sz, \
  31. 0, \
  32. &ossl_bignum_dh##tag##_p, &ossl_bignum_dh##tag##_q, \
  33. &ossl_bignum_dh##tag##_g \
  34. }
  35. #else
  36. # define FFDHE(sz, keylength) { SN_ffdhe##sz, NID_ffdhe##sz }
  37. # define MODP(sz, keylength) { SN_modp_##sz, NID_modp_##sz }
  38. # define RFC5114(name, uid, sz, tag) { name, uid }
  39. #endif
  40. struct dh_named_group_st {
  41. const char *name;
  42. int uid;
  43. #ifndef OPENSSL_NO_DH
  44. int32_t nbits;
  45. int keylength;
  46. const BIGNUM *p;
  47. const BIGNUM *q;
  48. const BIGNUM *g;
  49. #endif
  50. };
  51. /*
  52. * The private key length values are taken from RFC7919 with the values for
  53. * MODP primes given the same lengths as the equivalent FFDHE.
  54. * The MODP 1536 value is approximated.
  55. */
  56. static const DH_NAMED_GROUP dh_named_groups[] = {
  57. FFDHE(2048, 225),
  58. FFDHE(3072, 275),
  59. FFDHE(4096, 325),
  60. FFDHE(6144, 375),
  61. FFDHE(8192, 400),
  62. #ifndef FIPS_MODULE
  63. MODP(1536, 200),
  64. #endif
  65. MODP(2048, 225),
  66. MODP(3072, 275),
  67. MODP(4096, 325),
  68. MODP(6144, 375),
  69. MODP(8192, 400),
  70. /*
  71. * Additional dh named groups from RFC 5114 that have a different g.
  72. * The uid can be any unique identifier.
  73. */
  74. #ifndef FIPS_MODULE
  75. RFC5114("dh_1024_160", 1, 1024, 1024_160),
  76. RFC5114("dh_2048_224", 2, 2048, 2048_224),
  77. RFC5114("dh_2048_256", 3, 2048, 2048_256),
  78. #endif
  79. };
  80. const DH_NAMED_GROUP *ossl_ffc_name_to_dh_named_group(const char *name)
  81. {
  82. size_t i;
  83. for (i = 0; i < OSSL_NELEM(dh_named_groups); ++i) {
  84. if (OPENSSL_strcasecmp(dh_named_groups[i].name, name) == 0)
  85. return &dh_named_groups[i];
  86. }
  87. return NULL;
  88. }
  89. const DH_NAMED_GROUP *ossl_ffc_uid_to_dh_named_group(int uid)
  90. {
  91. size_t i;
  92. for (i = 0; i < OSSL_NELEM(dh_named_groups); ++i) {
  93. if (dh_named_groups[i].uid == uid)
  94. return &dh_named_groups[i];
  95. }
  96. return NULL;
  97. }
  98. #ifndef OPENSSL_NO_DH
  99. const DH_NAMED_GROUP *ossl_ffc_numbers_to_dh_named_group(const BIGNUM *p,
  100. const BIGNUM *q,
  101. const BIGNUM *g)
  102. {
  103. size_t i;
  104. for (i = 0; i < OSSL_NELEM(dh_named_groups); ++i) {
  105. /* Keep searching until a matching p and g is found */
  106. if (BN_cmp(p, dh_named_groups[i].p) == 0
  107. && BN_cmp(g, dh_named_groups[i].g) == 0
  108. /* Verify q is correct if it exists */
  109. && (q == NULL || BN_cmp(q, dh_named_groups[i].q) == 0))
  110. return &dh_named_groups[i];
  111. }
  112. return NULL;
  113. }
  114. #endif
  115. int ossl_ffc_named_group_get_uid(const DH_NAMED_GROUP *group)
  116. {
  117. if (group == NULL)
  118. return NID_undef;
  119. return group->uid;
  120. }
  121. const char *ossl_ffc_named_group_get_name(const DH_NAMED_GROUP *group)
  122. {
  123. if (group == NULL)
  124. return NULL;
  125. return group->name;
  126. }
  127. #ifndef OPENSSL_NO_DH
  128. int ossl_ffc_named_group_get_keylength(const DH_NAMED_GROUP *group)
  129. {
  130. if (group == NULL)
  131. return 0;
  132. return group->keylength;
  133. }
  134. const BIGNUM *ossl_ffc_named_group_get_q(const DH_NAMED_GROUP *group)
  135. {
  136. if (group == NULL)
  137. return NULL;
  138. return group->q;
  139. }
  140. int ossl_ffc_named_group_set(FFC_PARAMS *ffc, const DH_NAMED_GROUP *group)
  141. {
  142. if (ffc == NULL || group == NULL)
  143. return 0;
  144. ossl_ffc_params_set0_pqg(ffc, (BIGNUM *)group->p, (BIGNUM *)group->q,
  145. (BIGNUM *)group->g);
  146. ffc->keylength = group->keylength;
  147. /* flush the cached nid, The DH layer is responsible for caching */
  148. ffc->nid = NID_undef;
  149. return 1;
  150. }
  151. #endif