ec_check.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. /*
  2. * Copyright 2002-2019 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. /*
  10. * ECDSA low level APIs are deprecated for public use, but still ok for
  11. * internal use.
  12. */
  13. #include "internal/deprecated.h"
  14. #include "ec_local.h"
  15. #include <openssl/err.h>
  16. int EC_GROUP_check_named_curve(const EC_GROUP *group, int nist_only,
  17. BN_CTX *ctx)
  18. {
  19. int nid = NID_undef;
  20. #ifndef FIPS_MODE
  21. BN_CTX *new_ctx = NULL;
  22. if (ctx == NULL) {
  23. ctx = new_ctx = BN_CTX_new();
  24. if (ctx == NULL) {
  25. ECerr(EC_F_EC_GROUP_CHECK_NAMED_CURVE, ERR_R_MALLOC_FAILURE);
  26. goto err;
  27. }
  28. }
  29. #endif
  30. nid = ec_curve_nid_from_params(group, ctx);
  31. if (nid > 0 && nist_only && EC_curve_nid2nist(nid) == NULL)
  32. nid = NID_undef;
  33. #ifndef FIPS_MODE
  34. err:
  35. BN_CTX_free(ctx);
  36. #endif
  37. return nid;
  38. }
  39. int EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx)
  40. {
  41. #ifdef FIPS_MODE
  42. /*
  43. * ECC domain parameter validation.
  44. * See SP800-56A R3 5.5.2 "Assurances of Domain-Parameter Validity" Part 1b.
  45. */
  46. return EC_GROUP_check_named_curve(group, 1, ctx) >= 0 ? 1 : 0;
  47. #else
  48. int ret = 0;
  49. const BIGNUM *order;
  50. BN_CTX *new_ctx = NULL;
  51. EC_POINT *point = NULL;
  52. if (group == NULL || group->meth == NULL) {
  53. ECerr(EC_F_EC_GROUP_CHECK, ERR_R_PASSED_NULL_PARAMETER);
  54. return 0;
  55. }
  56. /* Custom curves assumed to be correct */
  57. if ((group->meth->flags & EC_FLAGS_CUSTOM_CURVE) != 0)
  58. return 1;
  59. if (ctx == NULL) {
  60. ctx = new_ctx = BN_CTX_new();
  61. if (ctx == NULL) {
  62. ECerr(EC_F_EC_GROUP_CHECK, ERR_R_MALLOC_FAILURE);
  63. goto err;
  64. }
  65. }
  66. /* check the discriminant */
  67. if (!EC_GROUP_check_discriminant(group, ctx)) {
  68. ECerr(EC_F_EC_GROUP_CHECK, EC_R_DISCRIMINANT_IS_ZERO);
  69. goto err;
  70. }
  71. /* check the generator */
  72. if (group->generator == NULL) {
  73. ECerr(EC_F_EC_GROUP_CHECK, EC_R_UNDEFINED_GENERATOR);
  74. goto err;
  75. }
  76. if (EC_POINT_is_on_curve(group, group->generator, ctx) <= 0) {
  77. ECerr(EC_F_EC_GROUP_CHECK, EC_R_POINT_IS_NOT_ON_CURVE);
  78. goto err;
  79. }
  80. /* check the order of the generator */
  81. if ((point = EC_POINT_new(group)) == NULL)
  82. goto err;
  83. order = EC_GROUP_get0_order(group);
  84. if (order == NULL)
  85. goto err;
  86. if (BN_is_zero(order)) {
  87. ECerr(EC_F_EC_GROUP_CHECK, EC_R_UNDEFINED_ORDER);
  88. goto err;
  89. }
  90. if (!EC_POINT_mul(group, point, order, NULL, NULL, ctx))
  91. goto err;
  92. if (!EC_POINT_is_at_infinity(group, point)) {
  93. ECerr(EC_F_EC_GROUP_CHECK, EC_R_INVALID_GROUP_ORDER);
  94. goto err;
  95. }
  96. ret = 1;
  97. err:
  98. BN_CTX_free(new_ctx);
  99. EC_POINT_free(point);
  100. return ret;
  101. #endif /* FIPS_MODE */
  102. }