Exemple #1
0
int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
                                        const BIGNUM *x, const BIGNUM *y,
                                        BN_CTX *ctx) {
  if (group->meth != point->meth) {
    OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
    return 0;
  }
  if (!ec_GFp_simple_point_set_affine_coordinates(group, point, x, y, ctx)) {
    return 0;
  }

  if (!EC_POINT_is_on_curve(group, point, ctx)) {
    OPENSSL_PUT_ERROR(EC, EC_R_POINT_IS_NOT_ON_CURVE);
    return 0;
  }

  return 1;
}
Exemple #2
0
EC_POINT *GFp_suite_b_make_point(const EC_GROUP *group,
                                 const uint8_t *peer_public_key_x,
                                 size_t peer_public_key_x_len,
                                 const uint8_t *peer_public_key_y,
                                 size_t peer_public_key_y_len) {
  BIGNUM x;
  BN_init(&x);

  BIGNUM y;
  BN_init(&y);

  int ok = 0;

  EC_POINT *result = EC_POINT_new(group);
  if (result == NULL) {
    goto err;
  }

  /* |ec_GFp_simple_point_set_affine_coordinates| verifies that (x, y) is on
   * the curve and that each coordinate is a valid field element (i.e.
   * non-negative and less than `q`). The point cannot be the point at infinity
   * because it was given as affine coordinates. */
  if (BN_bin2bn(peer_public_key_x, peer_public_key_x_len, &x) == NULL ||
      BN_bin2bn(peer_public_key_y, peer_public_key_y_len, &y) == NULL ||
      !ec_GFp_simple_point_set_affine_coordinates(group, result, &x, &y,
                                                  NULL)) {
    goto err;
  }

  ok = 1;

err:
  BN_free(&x);
  BN_free(&y);
  if (!ok) {
    EC_POINT_free(result);
    result = NULL;
  }
  return result;
}
Exemple #3
0
static int ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
                                   const uint8_t *buf, size_t len,
                                   BN_CTX *ctx) {
  if (group->meth != point->meth) {
    OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
    return 0;
  }

  point_conversion_form_t form;
  int y_bit;
  BN_CTX *new_ctx = NULL;
  BIGNUM *x, *y;
  size_t field_len, enc_len;
  int ret = 0;

  if (len == 0) {
    OPENSSL_PUT_ERROR(EC, EC_R_BUFFER_TOO_SMALL);
    return 0;
  }
  form = buf[0];
  y_bit = form & 1;
  form = form & ~1U;
  if ((form != 0) && (form != POINT_CONVERSION_UNCOMPRESSED)) {
    OPENSSL_PUT_ERROR(EC, EC_R_INVALID_ENCODING);
    return 0;
  }
  if ((form == 0 || form == POINT_CONVERSION_UNCOMPRESSED) && y_bit) {
    OPENSSL_PUT_ERROR(EC, EC_R_INVALID_ENCODING);
    return 0;
  }

  if (form == 0) {
    if (len != 1) {
      OPENSSL_PUT_ERROR(EC, EC_R_INVALID_ENCODING);
      return 0;
    }

    return EC_POINT_set_to_infinity(group, point);
  }

  field_len = BN_num_bytes(&group->field);
  enc_len = 1 + 2 * field_len;

  if (len != enc_len) {
    OPENSSL_PUT_ERROR(EC, EC_R_INVALID_ENCODING);
    return 0;
  }

  if (ctx == NULL) {
    ctx = new_ctx = BN_CTX_new();
    if (ctx == NULL) {
      return 0;
    }
  }

  BN_CTX_start(ctx);
  x = BN_CTX_get(ctx);
  y = BN_CTX_get(ctx);
  if (x == NULL || y == NULL) {
    goto err;
  }

  if (!BN_bin2bn(buf + 1, field_len, x)) {
    goto err;
  }
  if (BN_ucmp(x, &group->field) >= 0) {
    OPENSSL_PUT_ERROR(EC, EC_R_INVALID_ENCODING);
    goto err;
  }

  if (!BN_bin2bn(buf + 1 + field_len, field_len, y)) {
    goto err;
  }
  if (BN_ucmp(y, &group->field) >= 0) {
    OPENSSL_PUT_ERROR(EC, EC_R_INVALID_ENCODING);
    goto err;
  }

  if (!ec_GFp_simple_point_set_affine_coordinates(group, point, x, y, ctx)) {
    goto err;
  }

  /* test required by X9.62 */
  if (!EC_POINT_is_on_curve(group, point, ctx)) {
    OPENSSL_PUT_ERROR(EC, EC_R_POINT_IS_NOT_ON_CURVE);
    goto err;
  }

  ret = 1;

err:
  BN_CTX_end(ctx);
  BN_CTX_free(new_ctx);
  return ret;
}