ffc_dh.c 5.2 KB

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