コード例 #1
0
ファイル: ec2_mult.c プロジェクト: Chenhx/moai-dev
/* Computes the sum
 *     scalar*group->generator + scalars[0]*points[0] + ... + scalars[num-1]*points[num-1]
 * gracefully ignoring NULL scalar values.
 */
int ec_GF2m_simple_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
	size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *ctx)
	{
	BN_CTX *new_ctx = NULL;
	int ret = 0;
	size_t i;
	EC_POINT *p=NULL;
	EC_POINT *acc = NULL;

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

	/* This implementation is more efficient than the wNAF implementation for 2
	 * or fewer points.  Use the ec_wNAF_mul implementation for 3 or more points,
	 * or if we can perform a fast multiplication based on precomputation.
	 */
	if ((scalar && (num > 1)) || (num > 2) || (num == 0 && EC_GROUP_have_precompute_mult(group)))
		{
		ret = ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx);
		goto err;
		}

	if ((p = EC_POINT_new(group)) == NULL) goto err;
	if ((acc = EC_POINT_new(group)) == NULL) goto err;

	if (!EC_POINT_set_to_infinity(group, acc)) goto err;

	if (scalar)
		{
		if (!ec_GF2m_montgomery_point_multiply(group, p, scalar, group->generator, ctx)) goto err;
		if (BN_is_negative(scalar))
			if (!group->meth->invert(group, p, ctx)) goto err;
		if (!group->meth->add(group, acc, acc, p, ctx)) goto err;
		}

	for (i = 0; i < num; i++)
		{
		if (!ec_GF2m_montgomery_point_multiply(group, p, scalars[i], points[i], ctx)) goto err;
		if (BN_is_negative(scalars[i]))
			if (!group->meth->invert(group, p, ctx)) goto err;
		if (!group->meth->add(group, acc, acc, p, ctx)) goto err;
		}

	if (!EC_POINT_copy(r, acc)) goto err;

	ret = 1;

  err:
	if (p) EC_POINT_free(p);
	if (acc) EC_POINT_free(acc);
	if (new_ctx != NULL)
		BN_CTX_free(new_ctx);
	return ret;
	}
コード例 #2
0
ファイル: a_enum.c プロジェクト: RobinWuDev/Qt
ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(BIGNUM *bn, ASN1_ENUMERATED *ai)
{
    ASN1_ENUMERATED *ret;
    int len,j;

    if (ai == NULL)
        ret=M_ASN1_ENUMERATED_new();
    else
        ret=ai;
    if (ret == NULL)
    {
        OPENSSL_PUT_ERROR(ASN1, BN_to_ASN1_ENUMERATED, ASN1_R_NESTED_ASN1_ERROR);
        goto err;
    }
    if(BN_is_negative(bn)) ret->type = V_ASN1_NEG_ENUMERATED;
    else ret->type=V_ASN1_ENUMERATED;
    j=BN_num_bits(bn);
    len=((j == 0)?0:((j/8)+1));
    if (ret->length < len+4)
    {
        unsigned char *new_data=OPENSSL_realloc(ret->data, len+4);
        if (!new_data)
        {
            OPENSSL_PUT_ERROR(ASN1, BN_to_ASN1_ENUMERATED, ERR_R_MALLOC_FAILURE);
            goto err;
        }
        ret->data=new_data;
    }

    ret->length=BN_bn2bin(bn,ret->data);
    return(ret);
err:
    if (ret != ai) M_ASN1_ENUMERATED_free(ret);
    return(NULL);
}
コード例 #3
0
ファイル: bcode.c プロジェクト: FreeBSDFoundation/freebsd
static void
store_array(void)
{
	struct number *inumber;
	struct value *value;
	struct stack *stack;
	u_long idx;
	int reg;

	reg = readreg();
	if (reg >= 0) {
		inumber = pop_number();
		if (inumber == NULL)
			return;
		value = pop();
		if (value == NULL) {
			free_number(inumber);
			return;
		}
		idx = get_ulong(inumber);
		if (BN_is_negative(inumber->number)) {
			warnx("negative idx");
			stack_free_value(value);
		} else if (idx == ULONG_MAX || idx > MAX_ARRAY_INDEX) {
			warnx("idx too big");
			stack_free_value(value);
		} else {
			stack = &bmachine.reg[reg];
			frame_assign(stack, idx, value);
		}
		free_number(inumber);
	}
}
コード例 #4
0
ファイル: bignumber.hpp プロジェクト: hpcc-systems/cpp-driver
  /**
   * Encode the varint using two's complement
   *
   * @return Vector of bytes in two's complement
   */
  std::vector<unsigned char> encode_varint() const {
    // Handle NULL and zero varint
    if (!big_number_ || BN_num_bytes(big_number_.get()) == 0) {
      std::vector<unsigned char> bytes(1);
      bytes[0] = 0x00;
      return bytes;
    }

    size_t number_of_bytes = BN_num_bytes(big_number_.get()) + 1;
    std::vector<unsigned char> bytes(number_of_bytes);
    if (BN_bn2bin(big_number_.get(), &bytes[1]) > 0) {
      // Set the sign and convert to two's complement (if necessary)
      if (BN_is_negative(big_number_.get())) {
        bool is_carry = true;
        for (ssize_t i = number_of_bytes - 1; i >= 0; --i) {
          bytes[i] ^= 0xFF;
          if (is_carry) {
            is_carry = ((++bytes[i]) == 0);
          }
        }
        bytes[0] |= 0x80;
      } else {
        bytes[0] = 0x00;
      }
    }

    return bytes;
  }
コード例 #5
0
ファイル: bn_asn1.c プロジェクト: reaperhulk/ring
int BN_bn2cbb(CBB *cbb, const BIGNUM *bn) {
  /* Negative numbers are unsupported. */
  if (BN_is_negative(bn)) {
    OPENSSL_PUT_ERROR(BN, BN_R_NEGATIVE_NUMBER);
    return 0;
  }

  CBB child;
  if (!CBB_add_asn1(cbb, &child, CBS_ASN1_INTEGER)) {
    OPENSSL_PUT_ERROR(BN, BN_R_ENCODE_ERROR);
    return 0;
  }

  /* The number must be padded with a leading zero if the high bit would
   * otherwise be set (or |bn| is zero). */
  if (BN_num_bits(bn) % 8 == 0 &&
      !CBB_add_u8(&child, 0x00)) {
    OPENSSL_PUT_ERROR(BN, BN_R_ENCODE_ERROR);
    return 0;
  }

  uint8_t *out;
  if (!CBB_add_space(&child, &out, BN_num_bytes(bn))) {
    OPENSSL_PUT_ERROR(BN, BN_R_ENCODE_ERROR);
    return 0;
  }
  BN_bn2bin(bn, out);
  if (!CBB_flush(cbb)) {
    OPENSSL_PUT_ERROR(BN, BN_R_ENCODE_ERROR);
    return 0;
  }
  return 1;
}
コード例 #6
0
ファイル: bcode.c プロジェクト: FreeBSDFoundation/freebsd
static void
load_array(void)
{
	struct number *inumber, *n;
	struct stack *stack;
	struct value *v;
	struct value copy;
	u_long idx;
	int reg;

	reg = readreg();
	if (reg >= 0) {
		inumber = pop_number();
		if (inumber == NULL)
			return;
		idx = get_ulong(inumber);
		if (BN_is_negative(inumber->number))
			warnx("negative idx");
		else if (idx == ULONG_MAX || idx > MAX_ARRAY_INDEX)
			warnx("idx too big");
		else {
			stack = &bmachine.reg[reg];
			v = frame_retrieve(stack, idx);
			if (v == NULL || v->type == BCODE_NONE) {
				n = new_number();
				bn_check(BN_zero(n->number));
				push_number(n);
			}
			else
				push(stack_dup_value(v, &copy));
		}
		free_number(inumber);
	}
}
コード例 #7
0
ファイル: bn8_misc.c プロジェクト: 12019/bitcoin-smartcard
void bn8_from_bn(bn8 r, const BIGNUM *a)
{
	int n = BN_num_bytes(a);
	memset(r, 0, BN8_SIZE);
	BN_bn2bin(a, r+1+(BN8_SIZE-1)-n);
	if(BN_is_negative(a))
		bn8_negative(r);
}
コード例 #8
0
ファイル: bigint.cpp プロジェクト: FollowMyVote/fc
 int64_t bigint::to_int64() const
 {
   FC_ASSERT(BN_num_bits(n) <= 63);
   size_t size = BN_num_bytes(n);
   uint64_t abs_value = 0;
   BN_bn2bin(n, (unsigned char*)&abs_value + (sizeof(uint64_t) - size));
   return BN_is_negative(n) ? -(int64_t)bswap_64(abs_value) : bswap_64(abs_value);
 }
コード例 #9
0
ファイル: rsa_impl.c プロジェクト: freeors/Rose
int rsa_greater_than_pow2(const BIGNUM *b, int n) {
  if (BN_is_negative(b) || n == INT_MAX) {
    return 0;
  }

  int b_bits = BN_num_bits(b);
  return b_bits > n + 1 || (b_bits == n + 1 && !BN_is_pow2(b));
}
コード例 #10
0
extern "C" int Java_java_math_NativeBN_sign(JNIEnv* env, jclass, jlong a) {
  if (!oneValidHandle(env, a)) return -2;
  if (BN_is_zero(toBigNum(a))) {
      return 0;
  } else if (BN_is_negative(toBigNum(a))) {
    return -1;
  }
  return 1;
}
コード例 #11
0
int
_hc_BN_to_integer(BIGNUM *bn, heim_integer *integer)
{
    integer->length = BN_num_bytes(bn);
    integer->data = malloc(integer->length);
    if (integer->data == NULL)
	return ENOMEM;
    BN_bn2bin(bn, integer->data);
    integer->negative = BN_is_negative(bn);
    return 0;
}
コード例 #12
0
ファイル: pkinit.c プロジェクト: heimdal/heimdal
static krb5_error_code
BN_to_integer(krb5_context context, BIGNUM *bn, heim_integer *integer)
{
    integer->length = BN_num_bytes(bn);
    integer->data = malloc(integer->length);
    if (integer->data == NULL) {
	krb5_clear_error_message(context);
	return ENOMEM;
    }
    BN_bn2bin(bn, integer->data);
    integer->negative = BN_is_negative(bn);
    return 0;
}
コード例 #13
0
ファイル: rsa.c プロジェクト: AllardJ/Tomato
static int
bn2heim_int(BIGNUM *bn, heim_integer *integer)
{
    integer->length = BN_num_bytes(bn);
    integer->data = malloc(integer->length);
    if (integer->data == NULL) {
	integer->length = 0;
	return ENOMEM;
    }
    BN_bn2bin(bn, integer->data);
    integer->negative = BN_is_negative(bn);
    return 0;
}
コード例 #14
0
ファイル: pgx_cert_utils.c プロジェクト: beargiles/pg-cert
/**
 * Convert BIGNUM to bytea. (Copied from pg-bignum)
 */
bytea * bignum_to_bytea(BIGNUM *bn) {
    int len;
    bytea *results;

    // create bytea results.
    len = BN_num_bytes(bn);
    results = (bytea *) palloc(len + 1 + VARHDRSZ);
    *VARDATA(results) = BN_is_negative(bn) ? 0x01 : 0x00;
    BN_bn2bin(bn, (unsigned char *) VARDATA(results) + 1);
    SET_VARSIZE(results, len + 1 + VARHDRSZ);

    return results;
}
コード例 #15
0
ファイル: t_pkey.c プロジェクト: 2trill2spill/nextgen
int
ASN1_bn_print(BIO *bp, const char *number, const BIGNUM *num,
    unsigned char *buf, int off)
{
	int n, i;
	const char *neg;

	if (num == NULL)
		return (1);
	neg = (BN_is_negative(num)) ? "-" : "";
	if (!BIO_indent(bp, off, 128))
		return 0;
	if (BN_is_zero(num)) {
		if (BIO_printf(bp, "%s 0\n", number) <= 0)
			return 0;
		return 1;
	}

	if (BN_num_bytes(num) <= BN_BYTES) {
		if (BIO_printf(bp, "%s %s%lu (%s0x%lx)\n", number, neg,
		    (unsigned long)num->d[0], neg,
		    (unsigned long)num->d[0]) <= 0)
			return (0);
	} else {
		buf[0] = 0;
		if (BIO_printf(bp, "%s%s", number,
		    (neg[0] == '-') ? " (Negative)" : "") <= 0)
			return (0);
		n = BN_bn2bin(num, &buf[1]);

		if (buf[1] & 0x80)
			n++;
		else
			buf++;

		for (i = 0; i < n; i++) {
			if ((i % 15) == 0) {
				if (BIO_puts(bp, "\n") <= 0 ||
				    !BIO_indent(bp, off + 4, 128))
					return 0;
			}
			if (BIO_printf(bp, "%02x%s", buf[i],
			    ((i + 1) == n) ? "" : ":") <= 0)
				return (0);
		}
		if (BIO_write(bp, "\n", 1) <= 0)
			return (0);
	}
	return (1);
}
コード例 #16
0
ファイル: t_pkey.c プロジェクト: mtrojnar/openssl
int ASN1_bn_print(BIO *bp, const char *number, const BIGNUM *num,
                  unsigned char *ign, int indent)
{
    int n, rv = 0;
    const char *neg;
    unsigned char *buf = NULL, *tmp = NULL;
    int buflen;

    if (num == NULL)
        return 1;
    neg = BN_is_negative(num) ? "-" : "";
    if (!BIO_indent(bp, indent, ASN1_PRINT_MAX_INDENT))
        return 0;
    if (BN_is_zero(num)) {
        if (BIO_printf(bp, "%s 0\n", number) <= 0)
            return 0;
        return 1;
    }

    if (BN_num_bytes(num) <= BN_BYTES) {
        if (BIO_printf(bp, "%s %s%lu (%s0x%lx)\n", number, neg,
                       (unsigned long)bn_get_words(num)[0], neg,
                       (unsigned long)bn_get_words(num)[0]) <= 0)
            return 0;
        return 1;
    }

    buflen = BN_num_bytes(num) + 1;
    buf = tmp = OPENSSL_malloc(buflen);
    if (buf == NULL)
        goto err;
    buf[0] = 0;
    if (BIO_printf(bp, "%s%s\n", number,
                   (neg[0] == '-') ? " (Negative)" : "") <= 0)
        goto err;
    n = BN_bn2bin(num, buf + 1);

    if (buf[1] & 0x80)
        n++;
    else
        tmp++;

    if (ASN1_buf_print(bp, tmp, n, indent + 4) == 0)
        goto err;
    rv = 1;
err:
    OPENSSL_clear_free(buf, buflen);
    return rv;
}
コード例 #17
0
/* g^x is a legal value */
static int is_legal(const BIGNUM *gx, const JPAKE_CTX *ctx)
    {
    BIGNUM *t;
    int res;
    
    if(BN_is_negative(gx) || BN_is_zero(gx) || BN_cmp(gx, ctx->p.p) >= 0)
	return 0;

    t = BN_new();
    BN_mod_exp(t, gx, ctx->p.q, ctx->p.p, ctx->ctx);
    res = BN_is_one(t);
    BN_free(t);

    return res;
    }
コード例 #18
0
static int set_Jprojective_coordinate_GFp(const EC_GROUP *group, BIGNUM *out,
                                          const BIGNUM *in, BN_CTX *ctx) {
  if (in == NULL) {
    return 1;
  }
  if (BN_is_negative(in) ||
      BN_cmp(in, &group->field) >= 0) {
    OPENSSL_PUT_ERROR(EC, EC_R_COORDINATES_OUT_OF_RANGE);
    return 0;
  }
  if (group->meth->field_encode) {
    return group->meth->field_encode(group, out, in, ctx);
  }
  return BN_copy(out, in) != NULL;
}
コード例 #19
0
ファイル: rsa.c プロジェクト: 0x64616E69656C/boringssl
static int check_mod_inverse(int *out_ok, const BIGNUM *a, const BIGNUM *ainv,
                             const BIGNUM *m, int check_reduced, BN_CTX *ctx) {
  BN_CTX_start(ctx);
  BIGNUM *tmp = BN_CTX_get(ctx);
  int ret = tmp != NULL &&
            bn_mul_consttime(tmp, a, ainv, ctx) &&
            bn_div_consttime(NULL, tmp, tmp, m, ctx);
  if (ret) {
    *out_ok = BN_is_one(tmp);
    if (check_reduced && (BN_is_negative(ainv) || BN_cmp(ainv, m) >= 0)) {
      *out_ok = 0;
    }
  }
  BN_CTX_end(ctx);
  return ret;
}
コード例 #20
0
ファイル: bcode.c プロジェクト: darksoul42/bitrig
static void
bsqrt(void)
{
	struct number	*n;
	struct number	*r;
	BIGNUM		*x, *y;
	u_int		scale, onecount;
	BN_CTX		*ctx;

	onecount = 0;
	n = pop_number();
	if (n == NULL) {
		return;
	}
	if (BN_is_zero(n->number)) {
		r = new_number();
		push_number(r);
	} else if (BN_is_negative(n->number))
		warnx("square root of negative number");
	else {
		scale = max(bmachine.scale, n->scale);
		normalize(n, 2*scale);
		x = BN_dup(n->number);
		bn_checkp(x);
		bn_check(BN_rshift(x, x, BN_num_bits(x)/2));
		y = BN_new();
		bn_checkp(y);
		ctx = BN_CTX_new();
		bn_checkp(ctx);
		for (;;) {
			bn_checkp(BN_copy(y, x));
			bn_check(BN_div(x, NULL, n->number, x, ctx));
			bn_check(BN_add(x, x, y));
			bn_check(BN_rshift1(x, x));
			if (bsqrt_stop(x, y, &onecount))
				break;
		}
		r = bmalloc(sizeof(*r));
		r->scale = scale;
		r->number = y;
		BN_free(x);
		BN_CTX_free(ctx);
		push_number(r);
	}

	free_number(n);
}
コード例 #21
0
ファイル: dh.c プロジェクト: ozaki-r/netbsd-src
int
dh_pub_is_valid(const DH *dh, const BIGNUM *dh_pub)
{
	int i;
	int n = BN_num_bits(dh_pub);
	int bits_set = 0;
	BIGNUM *tmp;
	const BIGNUM *p;

	if (BN_is_negative(dh_pub)) {
		logit("invalid public DH value: negative");
		return 0;
	}
	if (BN_cmp(dh_pub, BN_value_one()) != 1) {	/* pub_exp <= 1 */
		logit("invalid public DH value: <= 1");
		return 0;
	}

	if ((tmp = BN_new()) == NULL) {
		error("%s: BN_new failed", __func__);
		return 0;
	}
	DH_get0_pqg(dh, &p, NULL, NULL);
	if (!BN_sub(tmp, p, BN_value_one()) ||
	    BN_cmp(dh_pub, tmp) != -1) {		/* pub_exp > p-2 */
		BN_clear_free(tmp);
		logit("invalid public DH value: >= p-1");
		return 0;
	}
	BN_clear_free(tmp);

	for (i = 0; i <= n; i++)
		if (BN_is_bit_set(dh_pub, i))
			bits_set++;
	debug2("bits set: %d/%d", bits_set, BN_num_bits(p));

	/*
	 * if g==2 and bits_set==1 then computing log_g(dh_pub) is trivial
	 */
	if (bits_set < 4) {
		logit("invalid public DH value (%d/%d)",
		   bits_set, BN_num_bits(p));
		return 0;
	}
	return 1;
}
コード例 #22
0
ファイル: a_int.c プロジェクト: 274914765/C
ASN1_INTEGER *BN_to_ASN1_INTEGER (const BIGNUM * bn, ASN1_INTEGER * ai)
{
    ASN1_INTEGER *ret;

    int len, j;

    if (ai == NULL)
        ret = M_ASN1_INTEGER_new ();
    else
        ret = ai;
    if (ret == NULL)
    {
        ASN1err (ASN1_F_BN_TO_ASN1_INTEGER, ERR_R_NESTED_ASN1_ERROR);
        goto err;
    }
    if (BN_is_negative (bn))
        ret->type = V_ASN1_NEG_INTEGER;
    else
        ret->type = V_ASN1_INTEGER;
    j = BN_num_bits (bn);
    len = ((j == 0) ? 0 : ((j / 8) + 1));
    if (ret->length < len + 4)
    {
        unsigned char *new_data = OPENSSL_realloc (ret->data, len + 4);

        if (!new_data)
        {
            ASN1err (ASN1_F_BN_TO_ASN1_INTEGER, ERR_R_MALLOC_FAILURE);
            goto err;
        }
        ret->data = new_data;
    }
    ret->length = BN_bn2bin (bn, ret->data);
    /* Correct zero case */
    if (!ret->length)
    {
        ret->data[0] = 0;
        ret->length = 1;
    }
    return (ret);
  err:
    if (ret != ai)
        M_ASN1_INTEGER_free (ret);
    return (NULL);
}
コード例 #23
0
ファイル: checks.c プロジェクト: kroeckx/x509lint
static void CheckSerial(X509 *x509)
{
	ASN1_INTEGER *serial = X509_get_serialNumber(x509);
	BIGNUM *bn_serial = ASN1_INTEGER_to_BN(serial, NULL);

	if (BN_is_negative(bn_serial) || BN_is_zero(bn_serial))
	{
		SetError(ERR_SERIAL_NOT_POSITIVE);
	}

	if (serial->length > 20)
	{
		SetError(ERR_SERIAL_TOO_LARGE);
	}

	CheckASN1_integer(serial);
	BN_free(bn_serial);
}
コード例 #24
0
ファイル: bcode.c プロジェクト: FreeBSDFoundation/freebsd
static void
set_scale(void)
{
	struct number *n;
	u_long scale;

	n = pop_number();
	if (n != NULL) {
		if (BN_is_negative(n->number))
			warnx("scale must be a nonnegative number");
		else {
			scale = get_ulong(n);
			if (scale != ULONG_MAX && scale <= UINT_MAX)
				bmachine.scale = (u_int)scale;
			else
				warnx("scale too large");
			}
		free_number(n);
	}
}
コード例 #25
0
ファイル: inout.c プロジェクト: kusumi/DragonFlyBSD
void
print_ascii(FILE *f, const struct number *n)
{
	BIGNUM *v;
	int numbits, i, ch;

	v = BN_dup(n->number);
	bn_checkp(v);

	if (BN_is_negative(v))
		BN_set_negative(v, 0);

	numbits = BN_num_bytes(v) * 8;
	while (numbits > 0) {
		ch = 0;
		for (i = 0; i < 8; i++)
			ch |= BN_is_bit_set(v, numbits-i-1) << (7 - i);
		putc(ch, f);
		numbits -= 8;
	}
	BN_free(v);
}
コード例 #26
0
ファイル: script_eval.c プロジェクト: digiwhite/picocoin
static int stackint(GPtrArray *stack, int index)
{
	struct buffer *buf = stacktop(stack, index);
	BIGNUM bn;
	BN_init(&bn);

	int ret = -1;

	if (!CastToBigNum(&bn, buf))
		goto out;

	if (!BN_is_negative(&bn))
		ret = BN_get_word(&bn);
	else {
		BN_set_negative(&bn, 0);
		ret = BN_get_word(&bn);
		ret = -ret;
	}

out:
	BN_clear_free(&bn);
	return ret;
}
コード例 #27
0
ファイル: ecs_ossl.c プロジェクト: izick/eme
static int ecdsa_do_verify(const unsigned char *dgst, int dgst_len,
		const ECDSA_SIG *sig, EC_KEY *eckey)
{
	int ret = -1, i;
	BN_CTX   *ctx;
	BIGNUM   *order, *u1, *u2, *m, *X;
	EC_POINT *point = NULL;
	const EC_GROUP *group;
	const EC_POINT *pub_key;

	/* check input values */
	if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL ||
	    (pub_key = EC_KEY_get0_public_key(eckey)) == NULL || sig == NULL)
	{
		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_MISSING_PARAMETERS);
		return -1;
	}

	ctx = BN_CTX_new();
	if (!ctx)
	{
		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
		return -1;
	}
	BN_CTX_start(ctx);
	order = BN_CTX_get(ctx);	
	u1    = BN_CTX_get(ctx);
	u2    = BN_CTX_get(ctx);
	m     = BN_CTX_get(ctx);
	X     = BN_CTX_get(ctx);
	if (!X)
	{
		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
		goto err;
	}
	
	if (!EC_GROUP_get_order(group, order, ctx))
	{
		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
		goto err;
	}

	if (BN_is_zero(sig->r)          || BN_is_negative(sig->r) || 
	    BN_ucmp(sig->r, order) >= 0 || BN_is_zero(sig->s)  ||
	    BN_is_negative(sig->s)      || BN_ucmp(sig->s, order) >= 0)
	{
		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_BAD_SIGNATURE);
		ret = 0;	/* signature is invalid */
		goto err;
	}
	/* calculate tmp1 = inv(S) mod order */
	if (!BN_mod_inverse(u2, sig->s, order, ctx))
	{
		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
		goto err;
	}
	/* digest -> m */
	i = BN_num_bits(order);
	/* Need to truncate digest if it is too long: first truncate whole
	 * bytes.
	 */
	if (8 * dgst_len > i)
		dgst_len = (i + 7)/8;
	if (!BN_bin2bn(dgst, dgst_len, m))
	{
		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
		goto err;
	}
	/* If still too long truncate remaining bits with a shift */
	if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7)))
	{
		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
		goto err;
	}
	/* u1 = m * tmp mod order */
	if (!BN_mod_mul(u1, m, u2, order, ctx))
	{
		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
		goto err;
	}
	/* u2 = r * w mod q */
	if (!BN_mod_mul(u2, sig->r, u2, order, ctx))
	{
		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
		goto err;
	}

	if ((point = EC_POINT_new(group)) == NULL)
	{
		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
		goto err;
	}
	if (!EC_POINT_mul(group, point, u1, pub_key, u2, ctx))
	{
		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, 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,
			point, X, NULL, ctx))
		{
			ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, 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,
			point, X, NULL, ctx))
		{
			ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
			goto err;
		}
	}
#endif	
	if (!BN_nnmod(u1, X, order, ctx))
	{
		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
		goto err;
	}
	/*  if the signature is correct u1 is equal to sig->r */
	ret = (BN_ucmp(u1, sig->r) == 0);
err:
	BN_CTX_end(ctx);
	BN_CTX_free(ctx);
	if (point)
		EC_POINT_free(point);
	return ret;
}
コード例 #28
0
ファイル: rsa_eay.c プロジェクト: mxOBS/debian_openssl
static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
	{
	BIGNUM *r1,*m1,*vrfy;
	BIGNUM local_dmp1, local_dmq1;
	BIGNUM *dmp1, *dmq1;
	int ret=0;

	BN_CTX_start(ctx);
	r1 = BN_CTX_get(ctx);
	m1 = BN_CTX_get(ctx);
	vrfy = BN_CTX_get(ctx);

	MONT_HELPER(rsa, ctx, p, rsa->flags & RSA_FLAG_CACHE_PRIVATE, goto err);
	MONT_HELPER(rsa, ctx, q, rsa->flags & RSA_FLAG_CACHE_PRIVATE, goto err);
	MONT_HELPER(rsa, ctx, n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err);

	if (!BN_mod(r1,I,rsa->q,ctx)) goto err;
	if (!(rsa->flags & RSA_FLAG_NO_EXP_CONSTTIME))
		{
		dmq1 = &local_dmq1;
		BN_with_flags(dmq1, rsa->dmq1, BN_FLG_EXP_CONSTTIME);
		}
	else
		dmq1 = rsa->dmq1;
	if (!rsa->meth->bn_mod_exp(m1,r1,dmq1,rsa->q,ctx,
		rsa->_method_mod_q)) goto err;

	if (!BN_mod(r1,I,rsa->p,ctx)) goto err;
	if (!(rsa->flags & RSA_FLAG_NO_EXP_CONSTTIME))
		{
		dmp1 = &local_dmp1;
		BN_with_flags(dmp1, rsa->dmp1, BN_FLG_EXP_CONSTTIME);
		}
	else
		dmp1 = rsa->dmp1;
	if (!rsa->meth->bn_mod_exp(r0,r1,dmp1,rsa->p,ctx,
		rsa->_method_mod_p)) goto err;

	if (!BN_sub(r0,r0,m1)) goto err;
	/* This will help stop the size of r0 increasing, which does
	 * affect the multiply if it optimised for a power of 2 size */
	if (BN_is_negative(r0))
		if (!BN_add(r0,r0,rsa->p)) goto err;

	if (!BN_mul(r1,r0,rsa->iqmp,ctx)) goto err;
	if (!BN_mod(r0,r1,rsa->p,ctx)) goto err;
	/* If p < q it is occasionally possible for the correction of
         * adding 'p' if r0 is negative above to leave the result still
	 * negative. This can break the private key operations: the following
	 * second correction should *always* correct this rare occurrence.
	 * This will *never* happen with OpenSSL generated keys because
         * they ensure p > q [steve]
         */
	if (BN_is_negative(r0))
		if (!BN_add(r0,r0,rsa->p)) goto err;
	if (!BN_mul(r1,r0,rsa->q,ctx)) goto err;
	if (!BN_add(r0,r1,m1)) goto err;

	if (rsa->e && rsa->n)
		{
		if (!rsa->meth->bn_mod_exp(vrfy,r0,rsa->e,rsa->n,ctx,rsa->_method_mod_n)) goto err;
		/* If 'I' was greater than (or equal to) rsa->n, the operation
		 * will be equivalent to using 'I mod n'. However, the result of
		 * the verify will *always* be less than 'n' so we don't check
		 * for absolute equality, just congruency. */
		if (!BN_sub(vrfy, vrfy, I)) goto err;
		if (!BN_mod(vrfy, vrfy, rsa->n, ctx)) goto err;
		if (BN_is_negative(vrfy))
			if (!BN_add(vrfy, vrfy, rsa->n)) goto err;
		if (!BN_is_zero(vrfy))
			{
			/* 'I' and 'vrfy' aren't congruent mod n. Don't leak
			 * miscalculated CRT output, just do a raw (slower)
			 * mod_exp and return that instead. */

			BIGNUM local_d;
			BIGNUM *d = NULL;
		
			if (!(rsa->flags & RSA_FLAG_NO_EXP_CONSTTIME))
				{
				d = &local_d;
				BN_with_flags(d, rsa->d, BN_FLG_EXP_CONSTTIME);
				}
			else
				d = rsa->d;
			if (!rsa->meth->bn_mod_exp(r0,I,d,rsa->n,ctx,
						   rsa->_method_mod_n)) goto err;
			}
		}
	ret=1;
err:
	BN_CTX_end(ctx);
	return(ret);
	}
コード例 #29
0
ファイル: dh.c プロジェクト: Henauxg/minix
int
DH_check_pubkey(const DH *dh, const BIGNUM *pub_key, int *codes)
{
    BIGNUM *bn = NULL, *sum = NULL;
    int ret = 0;

    *codes = 0;

    /**
     * Checks that the function performs are:
     * - pub_key is not negative
     */

    if (BN_is_negative(pub_key))
	goto out;

    /**
     * - pub_key > 1    and    pub_key < p - 1,
     *    to avoid small subgroups attack.
     */

    bn = BN_new();
    if (bn == NULL)
	goto out;

    if (!BN_set_word(bn, 1))
	goto out;

    if (BN_cmp(bn, pub_key) >= 0)
	*codes |= DH_CHECK_PUBKEY_TOO_SMALL;

    sum = BN_new();
    if (sum == NULL)
	goto out;

    BN_uadd(sum, pub_key, bn);

    if (BN_cmp(sum, dh->p) >= 0)
	*codes |= DH_CHECK_PUBKEY_TOO_LARGE;

    /**
     * - if g == 2, pub_key have more then one bit set,
     *   if bits set is 1, log_2(pub_key) is trival
     */

    if (!BN_set_word(bn, 2))
	goto out;

    if (BN_cmp(bn, dh->g) == 0) {
	unsigned i, n = BN_num_bits(pub_key);
	unsigned bits = 0;

	for (i = 0; i <= n; i++)
	    if (BN_is_bit_set(pub_key, i))
		bits++;

	if (bits < 2) {
	    *codes |= DH_CHECK_PUBKEY_TOO_SMALL;
	    goto out;
	}
    }

    ret = 1;
out:
    if (bn)
	BN_free(bn);
    if (sum)
	BN_free(sum);

    return ret;
}
コード例 #30
0
ファイル: rsa_impl.c プロジェクト: caiolima/webkit
static int mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) {
  assert(ctx != NULL);

  assert(rsa->n != NULL);
  assert(rsa->e != NULL);
  assert(rsa->d != NULL);
  assert(rsa->p != NULL);
  assert(rsa->q != NULL);
  assert(rsa->dmp1 != NULL);
  assert(rsa->dmq1 != NULL);
  assert(rsa->iqmp != NULL);

  BIGNUM *r1, *m1, *vrfy;
  BIGNUM local_dmp1, local_dmq1, local_c, local_r1;
  BIGNUM *dmp1, *dmq1, *c, *pr1;
  int ret = 0;
  size_t i, num_additional_primes = 0;

  if (rsa->additional_primes != NULL) {
    num_additional_primes = sk_RSA_additional_prime_num(rsa->additional_primes);
  }

  BN_CTX_start(ctx);
  r1 = BN_CTX_get(ctx);
  m1 = BN_CTX_get(ctx);
  vrfy = BN_CTX_get(ctx);
  if (r1 == NULL ||
      m1 == NULL ||
      vrfy == NULL) {
    goto err;
  }

  {
    BIGNUM local_p, local_q;
    BIGNUM *p = NULL, *q = NULL;

    /* Make sure BN_mod in Montgomery initialization uses BN_FLG_CONSTTIME. */
    BN_init(&local_p);
    p = &local_p;
    BN_with_flags(p, rsa->p, BN_FLG_CONSTTIME);

    BN_init(&local_q);
    q = &local_q;
    BN_with_flags(q, rsa->q, BN_FLG_CONSTTIME);

    if (!BN_MONT_CTX_set_locked(&rsa->mont_p, &rsa->lock, p, ctx) ||
        !BN_MONT_CTX_set_locked(&rsa->mont_q, &rsa->lock, q, ctx)) {
      goto err;
    }
  }

  if (!BN_MONT_CTX_set_locked(&rsa->mont_n, &rsa->lock, rsa->n, ctx)) {
    goto err;
  }

  /* compute I mod q */
  c = &local_c;
  BN_with_flags(c, I, BN_FLG_CONSTTIME);
  if (!BN_mod(r1, c, rsa->q, ctx)) {
    goto err;
  }

  /* compute r1^dmq1 mod q */
  dmq1 = &local_dmq1;
  BN_with_flags(dmq1, rsa->dmq1, BN_FLG_CONSTTIME);
  if (!BN_mod_exp_mont_consttime(m1, r1, dmq1, rsa->q, ctx, rsa->mont_q)) {
    goto err;
  }

  /* compute I mod p */
  c = &local_c;
  BN_with_flags(c, I, BN_FLG_CONSTTIME);
  if (!BN_mod(r1, c, rsa->p, ctx)) {
    goto err;
  }

  /* compute r1^dmp1 mod p */
  dmp1 = &local_dmp1;
  BN_with_flags(dmp1, rsa->dmp1, BN_FLG_CONSTTIME);
  if (!BN_mod_exp_mont_consttime(r0, r1, dmp1, rsa->p, ctx, rsa->mont_p)) {
    goto err;
  }

  if (!BN_sub(r0, r0, m1)) {
    goto err;
  }
  /* This will help stop the size of r0 increasing, which does
   * affect the multiply if it optimised for a power of 2 size */
  if (BN_is_negative(r0)) {
    if (!BN_add(r0, r0, rsa->p)) {
      goto err;
    }
  }

  if (!BN_mul(r1, r0, rsa->iqmp, ctx)) {
    goto err;
  }

  /* Turn BN_FLG_CONSTTIME flag on before division operation */
  pr1 = &local_r1;
  BN_with_flags(pr1, r1, BN_FLG_CONSTTIME);

  if (!BN_mod(r0, pr1, rsa->p, ctx)) {
    goto err;
  }

  /* If p < q it is occasionally possible for the correction of
   * adding 'p' if r0 is negative above to leave the result still
   * negative. This can break the private key operations: the following
   * second correction should *always* correct this rare occurrence.
   * This will *never* happen with OpenSSL generated keys because
   * they ensure p > q [steve] */
  if (BN_is_negative(r0)) {
    if (!BN_add(r0, r0, rsa->p)) {
      goto err;
    }
  }
  if (!BN_mul(r1, r0, rsa->q, ctx)) {
    goto err;
  }
  if (!BN_add(r0, r1, m1)) {
    goto err;
  }

  for (i = 0; i < num_additional_primes; i++) {
    /* multi-prime RSA. */
    BIGNUM local_exp, local_prime;
    BIGNUM *exp = &local_exp, *prime = &local_prime;
    RSA_additional_prime *ap =
        sk_RSA_additional_prime_value(rsa->additional_primes, i);

    BN_with_flags(exp, ap->exp, BN_FLG_CONSTTIME);
    BN_with_flags(prime, ap->prime, BN_FLG_CONSTTIME);

    /* c will already point to a BIGNUM with the correct flags. */
    if (!BN_mod(r1, c, prime, ctx)) {
      goto err;
    }

    if (!BN_MONT_CTX_set_locked(&ap->mont, &rsa->lock, prime, ctx) ||
        !BN_mod_exp_mont_consttime(m1, r1, exp, prime, ctx, ap->mont)) {
      goto err;
    }

    BN_set_flags(m1, BN_FLG_CONSTTIME);

    if (!BN_sub(m1, m1, r0) ||
        !BN_mul(m1, m1, ap->coeff, ctx) ||
        !BN_mod(m1, m1, prime, ctx) ||
        (BN_is_negative(m1) && !BN_add(m1, m1, prime)) ||
        !BN_mul(m1, m1, ap->r, ctx) ||
        !BN_add(r0, r0, m1)) {
      goto err;
    }
  }

  ret = 1;

err:
  BN_CTX_end(ctx);
  return ret;
}