示例#1
0
static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in,
                            BIGNUM **kinvp, BIGNUM **rp,
                            const unsigned char *dgst, int dlen)
{
    BN_CTX *ctx = NULL;
    BIGNUM *k = NULL, *r = NULL, *order = NULL, *X = NULL;
    EC_POINT *tmp_point = NULL;
    const EC_GROUP *group;
    int ret = 0;

    if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL) {
        ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_PASSED_NULL_PARAMETER);
        return 0;
    }

    if (ctx_in == NULL) {
        if ((ctx = BN_CTX_new()) == NULL) {
            ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_MALLOC_FAILURE);
            return 0;
        }
    } else
        ctx = ctx_in;

    k = BN_new();               /* this value is later returned in *kinvp */
    r = BN_new();               /* this value is later returned in *rp */
    order = BN_new();
    X = BN_new();
    if (k == NULL || r == NULL || order == NULL || X == NULL) {
        ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_MALLOC_FAILURE);
        goto err;
    }
    if ((tmp_point = EC_POINT_new(group)) == NULL) {
        ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
        goto err;
    }
    if (!EC_GROUP_get_order(group, order, ctx)) {
        ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
        goto err;
    }

    do {
        /* get random k */
        do
            if (dgst != NULL) {
                if (!BN_generate_dsa_nonce
                    (k, order, EC_KEY_get0_private_key(eckey), dgst, dlen,
                     ctx)) {
                    ECerr(EC_F_ECDSA_SIGN_SETUP,
                             EC_R_RANDOM_NUMBER_GENERATION_FAILED);
                    goto err;
                }
            } else {
                if (!BN_rand_range(k, order)) {
                    ECerr(EC_F_ECDSA_SIGN_SETUP,
                             EC_R_RANDOM_NUMBER_GENERATION_FAILED);
                    goto err;
                }
            }
        while (BN_is_zero(k));

        /*
         * We do not want timing information to leak the length of k, so we
         * compute G*k using an equivalent scalar of fixed bit-length.
         */

        if (!BN_add(k, k, order))
            goto err;
        if (BN_num_bits(k) <= BN_num_bits(order))
            if (!BN_add(k, k, order))
                goto err;

        /* compute r the x-coordinate of generator * k */
        if (!EC_POINT_mul(group, tmp_point, k, NULL, NULL, ctx)) {
            ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
            goto err;
        }
        if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) ==
            NID_X9_62_prime_field) {
            if (!EC_POINT_get_affine_coordinates_GFp
                (group, tmp_point, X, NULL, ctx)) {
                ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
                goto err;
            }
        }
#ifndef OPENSSL_NO_EC2M
        else {                  /* NID_X9_62_characteristic_two_field */

            if (!EC_POINT_get_affine_coordinates_GF2m(group,
                                                      tmp_point, X, NULL,
                                                      ctx)) {
                ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
                goto err;
            }
        }
#endif
        if (!BN_nnmod(r, X, order, ctx)) {
            ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
            goto err;
        }
    }
    while (BN_is_zero(r));

    /* compute the inverse of k */
    if (EC_GROUP_get_mont_data(group) != NULL) {
        /*
         * We want inverse in constant time, therefore we utilize the fact
         * order must be prime and use Fermats Little Theorem instead.
         */
        if (!BN_set_word(X, 2)) {
            ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
            goto err;
        }
        if (!BN_mod_sub(X, order, X, order, ctx)) {
            ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
            goto err;
        }
        BN_set_flags(X, BN_FLG_CONSTTIME);
        if (!BN_mod_exp_mont_consttime
            (k, k, X, order, ctx, EC_GROUP_get_mont_data(group))) {
            ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
            goto err;
        }
    } else {
        if (!BN_mod_inverse(k, k, order, ctx)) {
            ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
            goto err;
        }
    }

    /* clear old values if necessary */
    BN_clear_free(*rp);
    BN_clear_free(*kinvp);
    /* save the pre-computed values  */
    *rp = r;
    *kinvp = k;
    ret = 1;
 err:
    if (!ret) {
        BN_clear_free(k);
        BN_clear_free(r);
    }
    if (ctx != ctx_in)
        BN_CTX_free(ctx);
    BN_free(order);
    EC_POINT_free(tmp_point);
    BN_clear_free(X);
    return (ret);
}
示例#2
0
文件: ecdsa.c 项目: dconnolly/ring
static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
                            BIGNUM **rp, const uint8_t *digest,
                            size_t digest_len) {
  BN_CTX *ctx = NULL;
  BIGNUM *k = NULL, *r = NULL, *order = NULL, *X = NULL;
  EC_POINT *tmp_point = NULL;
  const EC_GROUP *group;
  int ret = 0;

  if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL) {
    OPENSSL_PUT_ERROR(ECDSA, ERR_R_PASSED_NULL_PARAMETER);
    return 0;
  }

  if (ctx_in == NULL) {
    if ((ctx = BN_CTX_new()) == NULL) {
      OPENSSL_PUT_ERROR(ECDSA, ERR_R_MALLOC_FAILURE);
      return 0;
    }
  } else {
    ctx = ctx_in;
  }

  k = BN_new(); /* this value is later returned in *kinvp */
  r = BN_new(); /* this value is later returned in *rp    */
  order = BN_new();
  X = BN_new();
  if (!k || !r || !order || !X) {
    OPENSSL_PUT_ERROR(ECDSA, ERR_R_MALLOC_FAILURE);
    goto err;
  }
  tmp_point = EC_POINT_new(group);
  if (tmp_point == NULL) {
    OPENSSL_PUT_ERROR(ECDSA, ERR_R_EC_LIB);
    goto err;
  }
  if (!EC_GROUP_get_order(group, order, ctx)) {
    OPENSSL_PUT_ERROR(ECDSA, ERR_R_EC_LIB);
    goto err;
  }

  do {
    /* If possible, we'll include the private key and message digest in the k
     * generation. The |digest| argument is only empty if |ECDSA_sign_setup| is
     * being used. */
    do {
      int ok;

      if (digest_len > 0) {
        ok = BN_generate_dsa_nonce(k, order, EC_KEY_get0_private_key(eckey),
                                   digest, digest_len, ctx);
      } else {
        ok = BN_rand_range(k, order);
      }
      if (!ok) {
        OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED);
        goto err;
      }
    } while (BN_is_zero(k));

    /* We do not want timing information to leak the length of k,
     * so we compute G*k using an equivalent scalar of fixed
     * bit-length. */

    if (!BN_add(k, k, order)) {
      goto err;
    }
    if (BN_num_bits(k) <= BN_num_bits(order)) {
      if (!BN_add(k, k, order)) {
        goto err;
      }
    }

    /* compute r the x-coordinate of generator * k */
    if (!EC_POINT_mul(group, tmp_point, k, NULL, NULL, ctx)) {
      OPENSSL_PUT_ERROR(ECDSA, ERR_R_EC_LIB);
      goto err;
    }
    if (!EC_POINT_get_affine_coordinates_GFp(group, tmp_point, X, NULL, ctx)) {
      OPENSSL_PUT_ERROR(ECDSA, ERR_R_EC_LIB);
      goto err;
    }

    if (!BN_nnmod(r, X, order, ctx)) {
      OPENSSL_PUT_ERROR(ECDSA, ERR_R_BN_LIB);
      goto err;
    }
  } while (BN_is_zero(r));

  /* compute the inverse of k */
  if (!BN_mod_inverse(k, k, order, ctx)) {
    OPENSSL_PUT_ERROR(ECDSA, ERR_R_BN_LIB);
    goto err;
  }
  /* clear old values if necessary */
  BN_clear_free(*rp);
  BN_clear_free(*kinvp);

  /* save the pre-computed values  */
  *rp = r;
  *kinvp = k;
  ret = 1;

err:
  if (!ret) {
    BN_clear_free(k);
    BN_clear_free(r);
  }
  if (ctx_in == NULL) {
    BN_CTX_free(ctx);
  }
  BN_free(order);
  EC_POINT_free(tmp_point);
  BN_clear_free(X);
  return ret;
}
示例#3
0
static int ecdsa_sign_setup(const EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
                            BIGNUM **rp, const uint8_t *digest,
                            size_t digest_len) {
  BN_CTX *ctx = NULL;
  BIGNUM *k = NULL, *kinv = NULL, *r = NULL, *tmp = NULL;
  EC_POINT *tmp_point = NULL;
  const EC_GROUP *group;
  int ret = 0;

  if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL) {
    OPENSSL_PUT_ERROR(ECDSA, ERR_R_PASSED_NULL_PARAMETER);
    return 0;
  }

  if (ctx_in == NULL) {
    if ((ctx = BN_CTX_new()) == NULL) {
      OPENSSL_PUT_ERROR(ECDSA, ERR_R_MALLOC_FAILURE);
      return 0;
    }
  } else {
    ctx = ctx_in;
  }

  k = BN_new();
  kinv = BN_new();  // this value is later returned in *kinvp
  r = BN_new();  // this value is later returned in *rp
  tmp = BN_new();
  if (k == NULL || kinv == NULL || r == NULL || tmp == NULL) {
    OPENSSL_PUT_ERROR(ECDSA, ERR_R_MALLOC_FAILURE);
    goto err;
  }
  tmp_point = EC_POINT_new(group);
  if (tmp_point == NULL) {
    OPENSSL_PUT_ERROR(ECDSA, ERR_R_EC_LIB);
    goto err;
  }

  const BIGNUM *order = EC_GROUP_get0_order(group);

  // Check that the size of the group order is FIPS compliant (FIPS 186-4
  // B.5.2).
  if (BN_num_bits(order) < 160) {
    OPENSSL_PUT_ERROR(ECDSA, EC_R_INVALID_GROUP_ORDER);
    goto err;
  }

  do {
    // If possible, we'll include the private key and message digest in the k
    // generation. The |digest| argument is only empty if |ECDSA_sign_setup| is
    // being used.
    if (eckey->fixed_k != NULL) {
      if (!BN_copy(k, eckey->fixed_k)) {
        goto err;
      }
    } else if (digest_len > 0) {
      do {
        if (!BN_generate_dsa_nonce(k, order, EC_KEY_get0_private_key(eckey),
                                   digest, digest_len, ctx)) {
          OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED);
          goto err;
        }
      } while (BN_is_zero(k));
    } else if (!BN_rand_range_ex(k, 1, order)) {
      OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED);
      goto err;
    }

    // Compute the inverse of k. The order is a prime, so use Fermat's Little
    // Theorem. Note |ec_group_get_order_mont| may return NULL but
    // |bn_mod_inverse_prime| allows this.
    if (!bn_mod_inverse_prime(kinv, k, order, ctx,
                              ec_group_get_order_mont(group))) {
      OPENSSL_PUT_ERROR(ECDSA, ERR_R_BN_LIB);
      goto err;
    }

    // We do not want timing information to leak the length of k,
    // so we compute G*k using an equivalent scalar of fixed
    // bit-length.

    if (!BN_add(k, k, order)) {
      goto err;
    }
    if (BN_num_bits(k) <= BN_num_bits(order)) {
      if (!BN_add(k, k, order)) {
        goto err;
      }
    }

    // compute r the x-coordinate of generator * k
    if (!EC_POINT_mul(group, tmp_point, k, NULL, NULL, ctx)) {
      OPENSSL_PUT_ERROR(ECDSA, ERR_R_EC_LIB);
      goto err;
    }
    if (!EC_POINT_get_affine_coordinates_GFp(group, tmp_point, tmp, NULL,
                                             ctx)) {
      OPENSSL_PUT_ERROR(ECDSA, ERR_R_EC_LIB);
      goto err;
    }

    if (!BN_nnmod(r, tmp, order, ctx)) {
      OPENSSL_PUT_ERROR(ECDSA, ERR_R_BN_LIB);
      goto err;
    }
  } while (BN_is_zero(r));

  // clear old values if necessary
  BN_clear_free(*rp);
  BN_clear_free(*kinvp);

  // save the pre-computed values
  *rp = r;
  *kinvp = kinv;
  ret = 1;

err:
  BN_clear_free(k);
  if (!ret) {
    BN_clear_free(kinv);
    BN_clear_free(r);
  }
  if (ctx_in == NULL) {
    BN_CTX_free(ctx);
  }
  EC_POINT_free(tmp_point);
  BN_clear_free(tmp);
  return ret;
}
示例#4
0
文件: ecdsa.c 项目: T-null/proto-quic
static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
                            BIGNUM **rp, const uint8_t *digest,
                            size_t digest_len) {
  BN_CTX *ctx = NULL;
  BIGNUM *k = NULL, *r = NULL, *tmp = NULL;
  EC_POINT *tmp_point = NULL;
  const EC_GROUP *group;
  int ret = 0;

  if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL) {
    OPENSSL_PUT_ERROR(ECDSA, ERR_R_PASSED_NULL_PARAMETER);
    return 0;
  }

  if (ctx_in == NULL) {
    if ((ctx = BN_CTX_new()) == NULL) {
      OPENSSL_PUT_ERROR(ECDSA, ERR_R_MALLOC_FAILURE);
      return 0;
    }
  } else {
    ctx = ctx_in;
  }

  k = BN_new(); /* this value is later returned in *kinvp */
  r = BN_new(); /* this value is later returned in *rp    */
  tmp = BN_new();
  if (k == NULL || r == NULL || tmp == NULL) {
    OPENSSL_PUT_ERROR(ECDSA, ERR_R_MALLOC_FAILURE);
    goto err;
  }
  tmp_point = EC_POINT_new(group);
  if (tmp_point == NULL) {
    OPENSSL_PUT_ERROR(ECDSA, ERR_R_EC_LIB);
    goto err;
  }

  const BIGNUM *order = EC_GROUP_get0_order(group);

  do {
    /* If possible, we'll include the private key and message digest in the k
     * generation. The |digest| argument is only empty if |ECDSA_sign_setup| is
     * being used. */
    if (digest_len > 0) {
      do {
        if (!BN_generate_dsa_nonce(k, order, EC_KEY_get0_private_key(eckey),
                                   digest, digest_len, ctx)) {
          OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED);
          goto err;
        }
      } while (BN_is_zero(k));
    } else if (!BN_rand_range_ex(k, 1, order)) {
      OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED);
      goto err;
    }

    /* We do not want timing information to leak the length of k,
     * so we compute G*k using an equivalent scalar of fixed
     * bit-length. */

    if (!BN_add(k, k, order)) {
      goto err;
    }
    if (BN_num_bits(k) <= BN_num_bits(order)) {
      if (!BN_add(k, k, order)) {
        goto err;
      }
    }

    /* compute r the x-coordinate of generator * k */
    if (!EC_POINT_mul(group, tmp_point, k, NULL, NULL, ctx)) {
      OPENSSL_PUT_ERROR(ECDSA, ERR_R_EC_LIB);
      goto err;
    }
    if (!EC_POINT_get_affine_coordinates_GFp(group, tmp_point, tmp, NULL,
                                             ctx)) {
      OPENSSL_PUT_ERROR(ECDSA, ERR_R_EC_LIB);
      goto err;
    }

    if (!BN_nnmod(r, tmp, order, ctx)) {
      OPENSSL_PUT_ERROR(ECDSA, ERR_R_BN_LIB);
      goto err;
    }
  } while (BN_is_zero(r));

  /* Compute the inverse of k. The order is a prime, so use Fermat's Little
   * Theorem. */
  if (!BN_set_word(tmp, 2) ||
      !BN_sub(tmp, order, tmp) ||
      /* Note |ec_group_get_mont_data| may return NULL but |BN_mod_exp_mont|
       * allows it to be. */
      !BN_mod_exp_mont(k, k, tmp, order, ctx, ec_group_get_mont_data(group))) {
    OPENSSL_PUT_ERROR(ECDSA, ERR_R_BN_LIB);
    goto err;
  }
  /* clear old values if necessary */
  BN_clear_free(*rp);
  BN_clear_free(*kinvp);

  /* save the pre-computed values  */
  *rp = r;
  *kinvp = k;
  ret = 1;

err:
  if (!ret) {
    BN_clear_free(k);
    BN_clear_free(r);
  }
  if (ctx_in == NULL) {
    BN_CTX_free(ctx);
  }
  EC_POINT_free(tmp_point);
  BN_clear_free(tmp);
  return ret;
}