Exemplo n.º 1
0
/* The secret integers s0 and s1 must be in the range 0 < s < n for
   some n, and must be relatively prime to that n.  We know a priori
   that n is of the form 2**k * p for some small integer k and prime
   p.  Therefore, it suffices to choose a random integer in the range
   [0, n/2), multiply by two and add one (enforcing oddness), and then
   reject values which are divisible by p.  */
static BIGNUM *
random_s(const BIGNUM *n, const BIGNUM *p, BN_CTX *c)
{
  BIGNUM h, m, *r;

  BN_init(&h);
  BN_init(&m);
  FAILZ(r = BN_new());
  FAILZ(BN_copy(&h, n));
  FAILZ(BN_rshift1(&h, &h));

  do {
    FAILZ(BN_rand_range(r, &h));
    FAILZ(BN_lshift1(r, r));
    FAILZ(BN_add(r, r, BN_value_one()));
    FAILZ(BN_nnmod(&m, r, p, c));
  } while (BN_is_zero(&m));

  BN_clear(&h);
  BN_clear(&m);
  return r;

 fail:
  BN_clear(&h);
  BN_clear(&m);
  if (r) BN_clear_free(r);
  return 0;
}
Exemplo n.º 2
0
int
MKEM_decode_message(const MKEM *kp, uint8_t *secret, const uint8_t *message)
{
  int use_curve0 = !(message[0] & kp->params->curve_bit);
  const EC_GROUP *ca = use_curve0 ? kp->params->c0 : kp->params->c1;
  const BIGNUM *sa = use_curve0 ? kp->s0 : kp->s1;
  EC_POINT *q = 0, *r = 0;
  uint8_t *unpadded = 0;
  BIGNUM x, y;
  size_t mlen = kp->params->msgsize;
  int rv;

  if (!kp->s0 || !kp->s1) /* secret key not available */
    return -1;

  BN_init(&x);
  BN_init(&y);
  FAILZ(q = EC_POINT_new(ca));
  FAILZ(r = EC_POINT_new(ca));
  FAILZ(unpadded = malloc(mlen + 1));

  /* Copy the message, erase the padding bits, and put an 0x02 byte on
     the front so we can use EC_POINT_oct2point to recover the
     y-coordinate. */
  unpadded[0] = 0x02;
  unpadded[1] = (message[0] & ~(kp->params->pad_mask|kp->params->curve_bit));
  memcpy(&unpadded[2], &message[1], mlen - 1);

  FAILZ(EC_POINT_oct2point(ca, q, unpadded, mlen + 1,
                           kp->params->ctx));
  FAILZ(EC_POINT_mul(ca, r, 0, q, sa, kp->params->ctx));

  FAILZ(EC_POINT_get_affine_coordinates_GF2m(ca, q, &x, &y, kp->params->ctx));
  if (bn2bin_padhi(&x, secret, mlen) != mlen)
    goto fail;

  FAILZ(EC_POINT_get_affine_coordinates_GF2m(ca, r, &x, &y, kp->params->ctx));
  if (bn2bin_padhi(&x, secret + mlen, mlen) != mlen)
    goto fail;

  rv = 0;
 done:
  if (unpadded) {
    memset(unpadded, 0, mlen + 1);
    free(unpadded);
  }
  if (q) EC_POINT_clear_free(q);
  if (r) EC_POINT_clear_free(r);
  BN_clear(&x);
  BN_clear(&y);
  return rv;

 fail:
  rv = -1;
  memset(secret, 0, mlen * 2);
  goto done;
}
/**
 * Validates the format of the boot signature block, and checks that
 * the length in authenticated attributes matches the actual length of
 * the image.
 * @param bs The boot signature block to validate
 * @param length The actual length of the boot image without the signature
 */
static int validate_signature_block(const BootSignature *bs, uint64_t length)
{
    BIGNUM expected;
    BIGNUM value;
    int rc = -1;

    if (!bs) {
        return -1;
    }

    BN_init(&expected);
    BN_init(&value);

    /* Confirm that formatVersion matches our supported version */
    if (!BN_set_word(&expected, FORMAT_VERSION)) {
        ERR_print_errors(g_error);
        goto vsb_done;
    }

    ASN1_INTEGER_to_BN(bs->formatVersion, &value);

    if (BN_cmp(&expected, &value) != 0) {
        printf("Unsupported signature version\n");
        goto vsb_done;
    }

    BN_clear(&expected);
    BN_clear(&value);

    /* Confirm that the length of the image matches with the length in
        the authenticated attributes */
    length = htobe64(length);
    BN_bin2bn((const unsigned char *) &length, sizeof(length), &expected);

    ASN1_INTEGER_to_BN(bs->authenticatedAttributes->length, &value);

    if (BN_cmp(&expected, &value) != 0) {
        printf("Image length doesn't match signature attributes\n");
        goto vsb_done;
    }

    rc = 0;

vsb_done:
    BN_free(&expected);
    BN_free(&value);

    return rc;
}
Exemplo n.º 4
0
/**
 * Generate a prime number
 *
 * The internal CPRNG is seeded using the provided seed value.
 *
 * @param prime Pointer for storage of prime number
 * @param s Secret to share
 * @param bits Bit size of prime
 * @param rngSeed Seed value for CPRNG
 * @param rngSeedLength Length of Seed value for CPRNG
 *
 */
static int generatePrime(BIGNUM *prime, const BIGNUM *s, const int bits, unsigned char *rngSeed, const unsigned int rngSeedLength)
{
	int max_rounds = 1000;

	// Seed the RNG
	RAND_seed(rngSeed, rngSeedLength);

	// Clear the prime value
	BN_clear(prime);

	do {
		// Generate random prime
#if OPENSSL_VERSION_NUMBER  >= 0x00908000L /* last parm is BN_GENCB which is null in our case */
		BN_generate_prime_ex(prime, bits, 1, NULL, NULL, NULL);
#else
		BN_generate_prime(prime, bits, 1, NULL, NULL, NULL, NULL );
#endif

	} while ((BN_ucmp(prime, s) == -1) && (max_rounds-- > 0));	// If prime < s or not reached 1000 tries

	if (max_rounds > 0)
		return 0;
	else
		return -1; // We could not find a prime number
}
Exemplo n.º 5
0
int
dh_gen_key(DH *dh, int need)
{
	int pbits;
	const BIGNUM *p, *pub_key, *priv_key;

	DH_get0_pqg(dh, &p, NULL, NULL);

	if (need < 0 || p == NULL ||
	    (pbits = BN_num_bits(p)) <= 0 ||
	    need > INT_MAX / 2 || 2 * need > pbits)
		return SSH_ERR_INVALID_ARGUMENT;
	if (need < 256)
		need = 256;
	/*
	 * Pollard Rho, Big step/Little Step attacks are O(sqrt(n)),
	 * so double requested need here.
	 */
	DH_set_length(dh, MIN(need * 2, pbits - 1));
	if (DH_generate_key(dh) == 0) {
		return SSH_ERR_LIBCRYPTO_ERROR;
	}
	DH_get0_key(dh, &pub_key, &priv_key);
	if (!dh_pub_is_valid(dh, pub_key)) {
#if 0
		BN_clear(priv_key);
#endif
		return SSH_ERR_LIBCRYPTO_ERROR;
	}
	return 0;
}
Exemplo n.º 6
0
BIGNUM *
BN_bin2bn(const void *s, int len, BIGNUM *bn)
{
    heim_integer *hi = (void *)bn;

    if (len < 0)
	return NULL;

    if (hi == NULL) {
	hi = (heim_integer *)BN_new();
	if (hi == NULL)
	    return NULL;
    }
    if (hi->data)
	BN_clear((BIGNUM *)hi);
    hi->negative = 0;
    hi->data = malloc(len);
    if (hi->data == NULL && len != 0) {
	if (bn == NULL)
	    BN_free((BIGNUM *)hi);
	return NULL;
    }
    hi->length = len;
    memcpy(hi->data, s, len);
    return (BIGNUM *)hi;
}
Exemplo n.º 7
0
CHECK_RETVAL_BOOL \
static BOOLEAN selfTestGeneralOps1( void )
	{
	BIGNUM a;

	/* Simple tests that don't need the support of higher-level routines 
	   like importBignum() */
	BN_init( &a );
	if( !BN_zero( &a ) )
		return( FALSE );
	if( !BN_is_zero( &a ) || BN_is_one( &a ) )
		return( FALSE );
	if( !BN_is_word( &a, 0 ) || BN_is_word( &a, 1 ) )
		return( FALSE );
	if( BN_is_odd( &a ) )
		return( FALSE );
	if( BN_get_word( &a ) != 0 )
		return( FALSE );
	if( !BN_one( &a ) )
		return( FALSE );
	if( BN_is_zero( &a ) || !BN_is_one( &a ) )
		return( FALSE );
	if( BN_is_word( &a, 0 ) || !BN_is_word( &a, 1 ) )
		return( FALSE );
	if( !BN_is_odd( &a ) )
		return( FALSE );
	if( BN_num_bytes( &a ) != 1 )
		return( FALSE );
	if( BN_get_word( &a ) != 1 )
		return( FALSE );
	BN_clear( &a );

	return( TRUE );
	}
Exemplo n.º 8
0
int
BN_rand(BIGNUM *bn, int bits, int top, int bottom)
{
    size_t len = (bits + 7) / 8;
    heim_integer *i = (heim_integer *)bn;

    BN_clear(bn);

    i->negative = 0;
    i->data = malloc(len);
    if (i->data == NULL && len != 0)
	return 0;
    i->length = len;

    if (RAND_bytes(i->data, i->length) != 1) {
	free(i->data);
	i->data = NULL;
	return 0;
    }

    {
	size_t j = len * 8;
	while(j > bits) {
	    BN_clear_bit(bn, j - 1);
	    j--;
	}
    }

    if (top == -1) {
	;
    } else if (top == 0 && bits > 0) {
	BN_set_bit(bn, bits - 1);
    } else if (top == 1 && bits > 1) {
	BN_set_bit(bn, bits - 1);
	BN_set_bit(bn, bits - 2);
    } else {
	BN_clear(bn);
	return 0;
    }

    if (bottom && bits > 0)
	BN_set_bit(bn, 0);

    return 1;
}
Exemplo n.º 9
0
void
vg_exec_context_consolidate_key(vg_exec_context_t *vxcp)
{
	if (vxcp->vxc_delta) {
		BN_clear(&vxcp->vxc_bntmp);
		BN_set_word(&vxcp->vxc_bntmp, vxcp->vxc_delta);
		BN_add(&vxcp->vxc_bntmp2,
		       EC_KEY_get0_private_key(vxcp->vxc_key),
		       &vxcp->vxc_bntmp);
		vg_set_privkey(&vxcp->vxc_bntmp2, vxcp->vxc_key);
		vxcp->vxc_delta = 0;
	}
}
Exemplo n.º 10
0
static void
vg_prefix_range_sum(vg_prefix_t *vp, BIGNUM *result, BIGNUM *tmp1)
{
	vg_prefix_t *startp;

	startp = vp;
	BN_clear(result);
	do {
		BN_sub(tmp1, vp->vp_high, vp->vp_low);
		BN_add(result, result, tmp1);
		vp = vp->vp_sibling;
	} while (vp && (vp != startp));
}
Exemplo n.º 11
0
int
BN_uadd(BIGNUM *res, const BIGNUM *a, const BIGNUM *b)
{
    const heim_integer *ai = (const heim_integer *)a;
    const heim_integer *bi = (const heim_integer *)b;
    const unsigned char *ap, *bp;
    unsigned char *cp;
    heim_integer ci;
    int carry = 0;
    ssize_t len;

    if (ai->negative && bi->negative)
	return 0;
    if (ai->length < bi->length) {
	const heim_integer *si = bi;
	bi = ai; ai = si;
    }

    ci.negative = 0;
    ci.length = ai->length + 1;
    ci.data = malloc(ci.length);
    if (ci.data == NULL)
	return 0;

    ap = &((const unsigned char *)ai->data)[ai->length - 1];
    bp = &((const unsigned char *)bi->data)[bi->length - 1];
    cp = &((unsigned char *)ci.data)[ci.length - 1];

    for (len = bi->length; len > 0; len--) {
	carry = *ap + *bp + carry;
	*cp = carry & 0xff;
	carry = (carry & ~0xff) ? 1 : 0;
	ap--; bp--; cp--;
    }
    for (len = ai->length - bi->length; len > 0; len--) {
	carry = *ap + carry;
	*cp = carry & 0xff;
	carry = (carry & ~0xff) ? 1 : 0;
	ap--; cp--;
    }
    if (!carry)
	memmove(cp, cp + 1, --ci.length);
    else
	*cp = carry;

    BN_clear(res);
    *((heim_integer *)res) = ci;

    return 1;
}
Exemplo n.º 12
0
void
BN_CTX_end(BN_CTX *c)
{
    const size_t prev = c->stack.val[c->stack.used - 1];
    size_t i;

    if (c->stack.used == 0)
	abort();

    for (i = prev; i < c->bn.used; i++)
	BN_clear(c->bn.val[i]);

    c->stack.used--;
    c->bn.used = prev;
}
Exemplo n.º 13
0
/**
 * Generate a prime number
 *
 * The internal CPRNG is seeded using the provided seed value.
 * For the bit size of the generated prime the following condition holds:
 *
 * num_bits(prime) > max(2^r, num_bits(n + 1))
 *
 * r equals the number of bits needed to encode the secret.
 *
 * @param prime Pointer for storage of prime number
 * @param s Secret to share
 * @param n Maximum number of shares
 * @param rngSeed Seed value for CPRNG
 *
 */
static void generatePrime(BIGNUM *prime, const BIGNUM *s, const unsigned int n, char *rngSeed) {

	int bits = 0;

	// Seed the RNG
	RAND_seed(rngSeed, sizeof(rngSeed));

	// Determine minimum number of bits for prime >= max(2^r, n + 1)
	bits = BN_num_bits_word(n + 1) > BN_num_bits(s) ? (BN_num_bits_word(n + 1)) : (BN_num_bits(s));

	// Clear the prime value
	BN_clear(prime);

	// Generate random prime
	BN_generate_prime(prime, bits, 1, NULL, NULL, NULL, NULL );
}
Exemplo n.º 14
0
int
MKEM_generate_message(const MKEM *kp, uint8_t *secret, uint8_t *message)
{
  BIGNUM u;
  uint8_t pad;
  int rv = -1;
  BN_init(&u);
  if (BN_rand_range(&u, kp->params->maxu) &&
      BN_add(&u, &u, BN_value_one()) &&
      RAND_bytes(&pad, 1) &&
      !MKEM_generate_message_u(kp, &u, pad, secret, message))
    rv = 0;

  BN_clear(&u);
  return rv;
}
Exemplo n.º 15
0
static void
BN_POOL_reset(BN_POOL *p)
{
    BN_POOL_ITEM *item = p->head;
    while (item) {
        unsigned int loop = 0;
        BIGNUM *bn = item->vals;
        while (loop++ < BN_CTX_POOL_SIZE) {
            if (bn->d)
                BN_clear(bn);
            bn++;
        }
        item = item->next;
    }
    p->current = p->head;
    p->used = 0;
}
Exemplo n.º 16
0
static void
vg_prefix_context_clear_all_patterns(vg_context_t *vcp)
{
	vg_prefix_context_t *vcpp = (vg_prefix_context_t *) vcp;
	vg_prefix_t *vp;
	unsigned long npfx_left = 0;

	while (!avl_root_empty(&vcpp->vcp_avlroot)) {
		vp = avl_item_entry(vcpp->vcp_avlroot.ar_root,
				    vg_prefix_t, vp_item);
		vg_prefix_delete(&vcpp->vcp_avlroot, vp);
		npfx_left++;
	}

	assert(npfx_left == vcpp->base.vc_npatterns);
	vcpp->base.vc_npatterns = 0;
	vcpp->base.vc_npatterns_start = 0;
	vcpp->base.vc_found = 0;
	BN_clear(&vcpp->vcp_difficulty);
}
Exemplo n.º 17
0
double
vg_prefix_get_difficulty(int addrtype, const char *pattern)
{
	BN_CTX *bnctx;
	BIGNUM result, bntmp;
	BIGNUM *ranges[4];
	char *dbuf;
	int ret;
	double diffret = 0.0;

	bnctx = BN_CTX_new();
	BN_init(&result);
	BN_init(&bntmp);

	ret = get_prefix_ranges(addrtype,
				pattern, ranges, bnctx);

	if (ret == 0) {
		BN_sub(&bntmp, ranges[1], ranges[0]);
		BN_add(&result, &result, &bntmp);
		if (ranges[2]) {
			BN_sub(&bntmp, ranges[3], ranges[2]);
			BN_add(&result, &result, &bntmp);
		}
		free_ranges(ranges);

		BN_clear(&bntmp);
		BN_set_bit(&bntmp, 192);
		BN_div(&result, NULL, &bntmp, &result, bnctx);

		dbuf = BN_bn2dec(&result);
		diffret = strtod(dbuf, NULL);
		OPENSSL_free(dbuf);
	}

	BN_clear_free(&result);
	BN_clear_free(&bntmp);
	BN_CTX_free(bnctx);
	return diffret;
}
Exemplo n.º 18
0
static void
vg_prefix_context_next_difficulty(vg_prefix_context_t *vcpp,
				  BIGNUM *bntmp, BIGNUM *bntmp2, BN_CTX *bnctx)
{
	char *dbuf;

	BN_clear(bntmp);
	BN_set_bit(bntmp, 192);
	BN_div(bntmp2, NULL, bntmp, &vcpp->vcp_difficulty, bnctx);

	dbuf = BN_bn2dec(bntmp2);
	if (vcpp->base.vc_verbose > 0) {
		if (vcpp->base.vc_npatterns > 1)
			fprintf(stderr,
				"Next match difficulty: %s (%ld prefixes)\n",
				dbuf, vcpp->base.vc_npatterns);
		else
			fprintf(stderr, "Difficulty: %s\n", dbuf);
	}
	vcpp->base.vc_chance = atof(dbuf);
	OPENSSL_free(dbuf);
}
Exemplo n.º 19
0
void BN_CTX_clear( BN_CTX *bnCTX )
	{
	BN_POOL_ITEM *item = bnCTX->pool.head;

	/* Reset the bignum pool */
	while( item != NULL )
		{
		unsigned int loop = 0;
		BIGNUM *bn = item->vals;

		while( loop++ < BN_CTX_POOL_SIZE )
			{
			if( bn->d != NULL )
				BN_clear( bn );
			bn++;
			}
		item = item->next;
		}
	bnCTX->pool.current = bnCTX->pool.head;
	bnCTX->pool.used = 0;

	/* Reset the pool stack */
	bnCTX->stack.depth = 0;
	}
Exemplo n.º 20
0
int
MKEM_generate_message_u(const MKEM *kp, const BIGNUM *uraw, uint8_t pad,
                        uint8_t *secret, uint8_t *message)
{
  BIGNUM u, x, y;
  int use_curve0 = (BN_cmp(uraw, kp->params->n0) < 0);
  const EC_GROUP *ca;
  const EC_POINT *ga;
  const EC_POINT *pa;
  EC_POINT *q = 0, *r = 0;
  size_t mlen = kp->params->msgsize;
  int rv;

  BN_init(&u);
  BN_init(&x);
  BN_init(&y);

  if (use_curve0) {
    ca = kp->params->c0;
    ga = kp->params->g0;
    pa = kp->p0;
    FAILZ(BN_copy(&u, uraw));
  } else {
    ca = kp->params->c1;
    ga = kp->params->g1;
    pa = kp->p1;
    FAILZ(BN_sub(&u, uraw, kp->params->n0));
    FAILZ(BN_add(&u, &u, BN_value_one()));
  }

  FAILZ(q = EC_POINT_new(ca));
  FAILZ(r = EC_POINT_new(ca));
  FAILZ(EC_POINT_mul(ca, q, 0, ga, &u, kp->params->ctx));
  FAILZ(EC_POINT_mul(ca, r, 0, pa, &u, kp->params->ctx));

  FAILZ(EC_POINT_get_affine_coordinates_GF2m(ca, q, &x, &y, kp->params->ctx));
  if (bn2bin_padhi(&x, message, mlen) != mlen)
    goto fail;
  if (message[0] & (kp->params->pad_mask|kp->params->curve_bit)) /* see below */
    goto fail;
  memcpy(secret, message, mlen);

  FAILZ(EC_POINT_get_affine_coordinates_GF2m(ca, r, &x, &y, kp->params->ctx));
  if (bn2bin_padhi(&x, secret + mlen, mlen) != mlen)
    goto fail;

  /* K high bits of the message will be zero.  Fill in the high K-1
     of them with random bits from the pad, and use the lowest bit
     to identify the curve in use.  That bit will have a bias on the
     order of 2^{-d/2} where d is the bit-degree of the curve; 2^{-81}
     for the only curve presently implemented.  This is acceptably
     small since an elliptic curve of d bits gives only about d/2 bits
     of security anyway, and is much better than allowing a timing
     attack via the recipient having to attempt point decompression
     twice for curve 1 but only once for curve 0 (or, alternatively,
     doubling the time required for all decryptions).  */

  pad &= kp->params->pad_mask;
  pad |= (use_curve0 ? 0 : kp->params->curve_bit);
  message[0] |= pad;

  rv = 0;
 done:
  BN_clear(&u);
  BN_clear(&x);
  BN_clear(&y);
  if (q) EC_POINT_clear_free(q);
  if (r) EC_POINT_clear_free(r);
  return rv;

 fail:
  memset(message, 0, mlen);
  memset(secret, 0, mlen * 2);
  rv = -1;
  goto done;
}
Exemplo n.º 21
0
static int
vg_prefix_context_add_patterns(vg_context_t *vcp,
			       const char ** const patterns, int npatterns)
{
	vg_prefix_context_t *vcpp = (vg_prefix_context_t *) vcp;
	prefix_case_iter_t caseiter;
	vg_prefix_t *vp, *vp2;
	BN_CTX *bnctx;
	BIGNUM bntmp, bntmp2, bntmp3;
	BIGNUM *ranges[4];
	int ret = 0;
	int i, impossible = 0;
	int case_impossible;
	unsigned long npfx;
	char *dbuf;

	bnctx = BN_CTX_new();
	BN_init(&bntmp);
	BN_init(&bntmp2);
	BN_init(&bntmp3);

	npfx = 0;
	for (i = 0; i < npatterns; i++) {
		if (!vcpp->vcp_caseinsensitive) {
			vp = NULL;
			ret = get_prefix_ranges(vcpp->base.vc_addrtype,
						patterns[i],
						ranges, bnctx);
			if (!ret) {
				vp = vg_prefix_add_ranges(&vcpp->vcp_avlroot,
							  patterns[i],
							  ranges, NULL);
			}

		} else {
			/* Case-enumerate the prefix */
			if (!prefix_case_iter_init(&caseiter, patterns[i])) {
				fprintf(stderr,
					"Prefix '%s' is too long\n",
					patterns[i]);
				continue;
			}

			if (caseiter.ci_nbits > 16) {
				fprintf(stderr,
					"WARNING: Prefix '%s' has "
					"2^%d case-varied derivatives\n",
					patterns[i], caseiter.ci_nbits);
			}

			case_impossible = 0;
			vp = NULL;
			do {
				ret = get_prefix_ranges(vcpp->base.vc_addrtype,
							caseiter.ci_prefix,
							ranges, bnctx);
				if (ret == -2) {
					case_impossible++;
					ret = 0;
					continue;
				}
				if (ret)
					break;
				vp2 = vg_prefix_add_ranges(&vcpp->vcp_avlroot,
							   patterns[i],
							   ranges,
							   vp);
				if (!vp2) {
					ret = -1;
					break;
				}
				if (!vp)
					vp = vp2;

			} while (prefix_case_iter_next(&caseiter));

			if (!vp && case_impossible)
				ret = -2;

			if (ret && vp) {
				vg_prefix_delete(&vcpp->vcp_avlroot, vp);
				vp = NULL;
			}
		}

		if (ret == -2) {
			fprintf(stderr,
				"Prefix '%s' not possible\n", patterns[i]);
			impossible++;
		}

		if (!vp)
			continue;

		npfx++;

		/* Determine the probability of finding a match */
		vg_prefix_range_sum(vp, &bntmp, &bntmp2);
		BN_add(&bntmp2, &vcpp->vcp_difficulty, &bntmp);
		BN_copy(&vcpp->vcp_difficulty, &bntmp2);

		if (vcp->vc_verbose > 1) {
			BN_clear(&bntmp2);
			BN_set_bit(&bntmp2, 192);
			BN_div(&bntmp3, NULL, &bntmp2, &bntmp, bnctx);

			dbuf = BN_bn2dec(&bntmp3);
			fprintf(stderr,
				"Prefix difficulty: %20s %s\n",
				dbuf, patterns[i]);
			OPENSSL_free(dbuf);
		}
	}

	vcpp->base.vc_npatterns += npfx;
	vcpp->base.vc_npatterns_start += npfx;

	if (!npfx && impossible) {
		const char *ats = "bitcoin", *bw = "\"1\"";
		switch (vcpp->base.vc_addrtype) {
		case 5:
			ats = "bitcoin script";
			bw = "\"3\"";
			break;
		case 111:
			ats = "testnet";
			bw = "\"m\" or \"n\"";
			break;
		case 52:
			ats = "namecoin";
			bw = "\"M\" or \"N\"";
			break;
		default:
			break;
		}
		fprintf(stderr,
			"Hint: valid %s addresses begin with %s\n", ats, bw);
	}

	if (npfx)
		vg_prefix_context_next_difficulty(vcpp, &bntmp, &bntmp2, bnctx);

	ret = (npfx != 0);

	BN_clear_free(&bntmp);
	BN_clear_free(&bntmp2);
	BN_clear_free(&bntmp3);
	BN_CTX_free(bnctx);
	return ret;
}
Exemplo n.º 22
0
CHECK_RETVAL_BOOL \
static BOOLEAN selfTestGeneralOps2( void )
	{
	BIGNUM a;
	int status;

	/* More complex tests that need higher-level routines like importBignum(),
	   run after the tests of components of importBignum() have concluded */
	BN_init( &a );
#if BN_BITS2 == 64
	status = importBignum( &a, "\x01\x00\x00\x00\x00\x00\x00\x00\x00", 9, 
						   1, 128, NULL, KEYSIZE_CHECK_NONE );
#else
	status = importBignum( &a, "\x01\x00\x00\x00\x00", 5, 1, 128, NULL, 
						   KEYSIZE_CHECK_NONE );
#endif /* 64- vs 32-bit */
	if( cryptStatusError( status ) )
		return( FALSE );
	if( BN_is_zero( &a ) || BN_is_one( &a ) )
		return( FALSE );
	if( BN_is_word( &a, 0 ) || BN_is_word( &a, 1 ) )
		return( FALSE );
	if( BN_is_odd( &a ) )
		return( FALSE );
	if( BN_get_word( &a ) != BN_NAN )
		return( FALSE );
	if( BN_num_bytes( &a ) != ( BN_BITS2 / 8 ) + 1 )
		return( FALSE );
	if( BN_num_bits( &a ) != BN_BITS2 + 1 )
		return( FALSE );
	if( !BN_is_bit_set( &a, BN_BITS2 ) )
		return( FALSE );
	if( BN_is_bit_set( &a, 17 ) || !BN_set_bit( &a, 17 ) || \
		!BN_is_bit_set( &a, 17 ) )
		return( FALSE );
#if BN_BITS2 == 64
	status = importBignum( &a, "\x01\x00\x00\x00\x00\x00\x00\x00\x01", 9, 
						   1, 128, NULL, KEYSIZE_CHECK_NONE );
#else
	status = importBignum( &a,	"\x01\x00\x00\x00\x01", 5, 1, 128, NULL,
						   KEYSIZE_CHECK_NONE );
#endif /* 64- vs 32-bit */
	if( cryptStatusError( status ) )
		return( FALSE );
	if( BN_is_zero( &a ) || BN_is_one( &a ) )
		return( FALSE );
	if( BN_is_word( &a, 0 ) || BN_is_word( &a, 1 ) )
		return( FALSE );
	if( !BN_is_odd( &a ) )
		return( FALSE );
	if( BN_num_bytes( &a ) != ( BN_BITS2 / 8 ) + 1 )
		return( FALSE );
	if( BN_get_word( &a ) != BN_NAN )
		return( FALSE );
	if( BN_num_bits( &a ) != BN_BITS2 + 1 )
		return( FALSE );
	if( !BN_is_bit_set( &a, BN_BITS2 ) )
		return( FALSE );
	if( BN_is_bit_set( &a, BN_BITS2 + 27 ) || \
		!BN_set_bit( &a, BN_BITS2 + 27 ) || \
		!BN_is_bit_set( &a, BN_BITS2 + 27 ) )
		return( FALSE );
	/* Setting a bit off the end of a bignum extends its size, which is why
	   the following value doesn't match the one from a few lines earlier */
	if( BN_num_bytes( &a ) != ( BN_BITS2 / 8 ) + 4 )
		return( FALSE );
	/* The bit index for indexing bits is zero-based (since 1 == 1 << 0) but
	   for counting bits is one-based, which is why the following comparison
	   looks wrong.  Yet another one of OpenSSL's many booby-traps */
	if( BN_num_bits( &a ) != BN_BITS2 + 28 )
		return( FALSE );
	BN_clear( &a );

	return( TRUE );
	}
Exemplo n.º 23
0
/*
 * Find the bignum ranges that produce a given prefix.
 */
static int
get_prefix_ranges(int addrtype, const char *pfx, BIGNUM **result,
		  BN_CTX *bnctx)
{
	int i, p, c;
	int zero_prefix = 0;
	int check_upper = 0;
	int b58pow, b58ceil, b58top = 0;
	int ret = -1;

	BIGNUM bntarg, bnceil, bnfloor;
	BIGNUM bnbase;
	BIGNUM *bnap, *bnbp, *bntp;
	BIGNUM *bnhigh = NULL, *bnlow = NULL, *bnhigh2 = NULL, *bnlow2 = NULL;
	BIGNUM bntmp, bntmp2;

	BN_init(&bntarg);
	BN_init(&bnceil);
	BN_init(&bnfloor);
	BN_init(&bnbase);
	BN_init(&bntmp);
	BN_init(&bntmp2);

	BN_set_word(&bnbase, 58);

	p = strlen(pfx);

	for (i = 0; i < p; i++) {
		c = vg_b58_reverse_map[(int)pfx[i]];
		if (c == -1) {
			fprintf(stderr,
				"Invalid character '%c' in prefix '%s'\n",
				pfx[i], pfx);
			goto out;
		}
		if (i == zero_prefix) {
			if (c == 0) {
				/* Add another zero prefix */
				zero_prefix++;
				if (zero_prefix > 19) {
					fprintf(stderr,
						"Prefix '%s' is too long\n",
						pfx);
					goto out;
				}
				continue;
			}

			/* First non-zero character */
			b58top = c;
			BN_set_word(&bntarg, c);

		} else {
			BN_set_word(&bntmp2, c);
			BN_mul(&bntmp, &bntarg, &bnbase, bnctx);
			BN_add(&bntarg, &bntmp, &bntmp2);
		}
	}

	/* Power-of-two ceiling and floor values based on leading 1s */
	BN_clear(&bntmp);
	BN_set_bit(&bntmp, 200 - (zero_prefix * 8));
	BN_sub(&bnceil, &bntmp, BN_value_one());
	BN_set_bit(&bnfloor, 192 - (zero_prefix * 8));

	bnlow = BN_new();
	bnhigh = BN_new();

	if (b58top) {
		/*
		 * If a non-zero was given in the prefix, find the
		 * numeric boundaries of the prefix.
		 */

		BN_copy(&bntmp, &bnceil);
		bnap = &bntmp;
		bnbp = &bntmp2;
		b58pow = 0;
		while (BN_cmp(bnap, &bnbase) > 0) {
			b58pow++;
			BN_div(bnbp, NULL, bnap, &bnbase, bnctx);
			bntp = bnap;
			bnap = bnbp;
			bnbp = bntp;
		}
		b58ceil = BN_get_word(bnap);

		if ((b58pow - (p - zero_prefix)) < 6) {
			/*
			 * Do not allow the prefix to constrain the
			 * check value, this is ridiculous.
			 */
			fprintf(stderr, "Prefix '%s' is too long\n", pfx);
			goto out;
		}

		BN_set_word(&bntmp2, b58pow - (p - zero_prefix));
		BN_exp(&bntmp, &bnbase, &bntmp2, bnctx);
		BN_mul(bnlow, &bntmp, &bntarg, bnctx);
		BN_sub(&bntmp2, &bntmp, BN_value_one());
		BN_add(bnhigh, bnlow, &bntmp2);

		if (b58top <= b58ceil) {
			/* Fill out the upper range too */
			check_upper = 1;
			bnlow2 = BN_new();
			bnhigh2 = BN_new();

			BN_mul(bnlow2, bnlow, &bnbase, bnctx);
			BN_mul(&bntmp2, bnhigh, &bnbase, bnctx);
			BN_set_word(&bntmp, 57);
			BN_add(bnhigh2, &bntmp2, &bntmp);

			/*
			 * Addresses above the ceiling will have one
			 * fewer "1" prefix in front than we require.
			 */
			if (BN_cmp(&bnceil, bnlow2) < 0) {
				/* High prefix is above the ceiling */
				check_upper = 0;
				BN_free(bnhigh2);
				bnhigh2 = NULL;
				BN_free(bnlow2);
				bnlow2 = NULL;
			}
			else if (BN_cmp(&bnceil, bnhigh2) < 0)
				/* High prefix is partly above the ceiling */
				BN_copy(bnhigh2, &bnceil);

			/*
			 * Addresses below the floor will have another
			 * "1" prefix in front instead of our target.
			 */
			if (BN_cmp(&bnfloor, bnhigh) >= 0) {
				/* Low prefix is completely below the floor */
				assert(check_upper);
				check_upper = 0;
				BN_free(bnhigh);
				bnhigh = bnhigh2;
				bnhigh2 = NULL;
				BN_free(bnlow);
				bnlow = bnlow2;
				bnlow2 = NULL;
			}			
			else if (BN_cmp(&bnfloor, bnlow) > 0) {
				/* Low prefix is partly below the floor */
				BN_copy(bnlow, &bnfloor);
			}
		}

	} else {
		BN_copy(bnhigh, &bnceil);
		BN_clear(bnlow);
	}

	/* Limit the prefix to the address type */
	BN_clear(&bntmp);
	BN_set_word(&bntmp, addrtype);
	BN_lshift(&bntmp2, &bntmp, 192);

	if (check_upper) {
		if (BN_cmp(&bntmp2, bnhigh2) > 0) {
			check_upper = 0;
			BN_free(bnhigh2);
			bnhigh2 = NULL;
			BN_free(bnlow2);
			bnlow2 = NULL;
		}
		else if (BN_cmp(&bntmp2, bnlow2) > 0)
			BN_copy(bnlow2, &bntmp2);
	}

	if (BN_cmp(&bntmp2, bnhigh) > 0) {
		if (!check_upper)
			goto not_possible;
		check_upper = 0;
		BN_free(bnhigh);
		bnhigh = bnhigh2;
		bnhigh2 = NULL;
		BN_free(bnlow);
		bnlow = bnlow2;
		bnlow2 = NULL;
	}
	else if (BN_cmp(&bntmp2, bnlow) > 0) {
		BN_copy(bnlow, &bntmp2);
	}

	BN_set_word(&bntmp, addrtype + 1);
	BN_lshift(&bntmp2, &bntmp, 192);

	if (check_upper) {
		if (BN_cmp(&bntmp2, bnlow2) < 0) {
			check_upper = 0;
			BN_free(bnhigh2);
			bnhigh2 = NULL;
			BN_free(bnlow2);
			bnlow2 = NULL;
		}
		else if (BN_cmp(&bntmp2, bnhigh2) < 0)
			BN_copy(bnlow2, &bntmp2);
	}

	if (BN_cmp(&bntmp2, bnlow) < 0) {
		if (!check_upper)
			goto not_possible;
		check_upper = 0;
		BN_free(bnhigh);
		bnhigh = bnhigh2;
		bnhigh2 = NULL;
		BN_free(bnlow);
		bnlow = bnlow2;
		bnlow2 = NULL;
	}
	else if (BN_cmp(&bntmp2, bnhigh) < 0) {
		BN_copy(bnhigh, &bntmp2);
	}

	/* Address ranges are complete */
	assert(check_upper || ((bnlow2 == NULL) && (bnhigh2 == NULL)));
	result[0] = bnlow;
	result[1] = bnhigh;
	result[2] = bnlow2;
	result[3] = bnhigh2;
	bnlow = NULL;
	bnhigh = NULL;
	bnlow2 = NULL;
	bnhigh2 = NULL;
	ret = 0;

	if (0) {
	not_possible:
		ret = -2;
	}

out:
	BN_clear_free(&bntarg);
	BN_clear_free(&bnceil);
	BN_clear_free(&bnfloor);
	BN_clear_free(&bnbase);
	BN_clear_free(&bntmp);
	BN_clear_free(&bntmp2);
	if (bnhigh)
		BN_free(bnhigh);
	if (bnlow)
		BN_free(bnlow);
	if (bnhigh2)
		BN_free(bnhigh2);
	if (bnlow2)
		BN_free(bnlow2);

	return ret;
}
Exemplo n.º 24
0
void
BN_free(BIGNUM *bn)
{
    BN_clear(bn);
    free(bn);
}
Exemplo n.º 25
0
static int
test_BN_bit(void)
{
    BIGNUM *bn;
    int ret = 0;

    bn = BN_new();

    /* test setting and getting of "word" */
    if (!BN_set_word(bn, 1))
	return 1;
    if (!BN_is_bit_set(bn, 0))
	ret += 1;
    if (!BN_is_bit_set(bn, 0))
	ret += 1;

    if (!BN_set_word(bn, 2))
	return 1;
    if (!BN_is_bit_set(bn, 1))
	ret += 1;

    if (!BN_set_word(bn, 3))
	return 1;
    if (!BN_is_bit_set(bn, 0))
	ret += 1;
    if (!BN_is_bit_set(bn, 1))
	ret += 1;

    if (!BN_set_word(bn, 0x100))
	return 1;
    if (!BN_is_bit_set(bn, 8))
	ret += 1;

    if (!BN_set_word(bn, 0x1000))
	return 1;
    if (!BN_is_bit_set(bn, 12))
	ret += 1;

    /* test bitsetting */
    if (!BN_set_word(bn, 1))
	return 1;
    if (!BN_set_bit(bn, 1))
	return 1;
    if (BN_get_word(bn) != 3)
	return 1;
    if (!BN_clear_bit(bn, 0))
	return 1;
    if (BN_get_word(bn) != 2)
	return 1;

    /* test bitsetting past end of current end */
    BN_clear(bn);
    if (!BN_set_bit(bn, 12))
	return 1;
    if (BN_get_word(bn) != 0x1000)
	return 1;

    /* test bit and byte counting functions */
    if (BN_num_bits(bn) != 13)
	return 1;
    if (BN_num_bytes(bn) != 2)
	return 1;

    BN_free(bn);
    return ret;
}
Exemplo n.º 26
0
/*
 * Refer to FIPS 186-4 C.3.2 Enhanced Miller-Rabin Probabilistic Primality Test.
 * OR C.3.1 Miller-Rabin Probabilistic Primality Test (if enhanced is zero).
 * The Step numbers listed in the code refer to the enhanced case.
 *
 * if enhanced is set, then status returns one of the following:
 *     BN_PRIMETEST_PROBABLY_PRIME
 *     BN_PRIMETEST_COMPOSITE_WITH_FACTOR
 *     BN_PRIMETEST_COMPOSITE_NOT_POWER_OF_PRIME
 * if enhanced is zero, then status returns either
 *     BN_PRIMETEST_PROBABLY_PRIME or
 *     BN_PRIMETEST_COMPOSITE
 *
 * returns 0 if there was an error, otherwise it returns 1.
 */
int bn_miller_rabin_is_prime(const BIGNUM *w, int iterations, BN_CTX *ctx,
                             BN_GENCB *cb, int enhanced, int *status)
{
    int i, j, a, ret = 0;
    BIGNUM *g, *w1, *w3, *x, *m, *z, *b;
    BN_MONT_CTX *mont = NULL;

    /* w must be odd */
    if (!BN_is_odd(w))
        return 0;

    BN_CTX_start(ctx);
    g = BN_CTX_get(ctx);
    w1 = BN_CTX_get(ctx);
    w3 = BN_CTX_get(ctx);
    x = BN_CTX_get(ctx);
    m = BN_CTX_get(ctx);
    z = BN_CTX_get(ctx);
    b = BN_CTX_get(ctx);

    if (!(b != NULL
            /* w1 := w - 1 */
            && BN_copy(w1, w)
            && BN_sub_word(w1, 1)
            /* w3 := w - 3 */
            && BN_copy(w3, w)
            && BN_sub_word(w3, 3)))
        goto err;

    /* check w is larger than 3, otherwise the random b will be too small */
    if (BN_is_zero(w3) || BN_is_negative(w3))
        goto err;

    /* (Step 1) Calculate largest integer 'a' such that 2^a divides w-1 */
    a = 1;
    while (!BN_is_bit_set(w1, a))
        a++;
    /* (Step 2) m = (w-1) / 2^a */
    if (!BN_rshift(m, w1, a))
        goto err;

    /* Montgomery setup for computations mod a */
    mont = BN_MONT_CTX_new();
    if (mont == NULL || !BN_MONT_CTX_set(mont, w, ctx))
        goto err;

    if (iterations == BN_prime_checks)
        iterations = BN_prime_checks_for_size(BN_num_bits(w));

    /* (Step 4) */
    for (i = 0; i < iterations; ++i) {
        /* (Step 4.1) obtain a Random string of bits b where 1 < b < w-1 */
        if (!BN_priv_rand_range(b, w3) || !BN_add_word(b, 2)) /* 1 < b < w-1 */
            goto err;

        if (enhanced) {
            /* (Step 4.3) */
            if (!BN_gcd(g, b, w, ctx))
                goto err;
            /* (Step 4.4) */
            if (!BN_is_one(g)) {
                *status = BN_PRIMETEST_COMPOSITE_WITH_FACTOR;
                ret = 1;
                goto err;
            }
        }
        /* (Step 4.5) z = b^m mod w */
        if (!BN_mod_exp_mont(z, b, m, w, ctx, mont))
            goto err;
        /* (Step 4.6) if (z = 1 or z = w-1) */
        if (BN_is_one(z) || BN_cmp(z, w1) == 0)
            goto outer_loop;
        /* (Step 4.7) for j = 1 to a-1 */
        for (j = 1; j < a ; ++j) {
            /* (Step 4.7.1 - 4.7.2) x = z. z = x^2 mod w */
            if (!BN_copy(x, z) || !BN_mod_mul(z, x, x, w, ctx))
                goto err;
            /* (Step 4.7.3) */
            if (BN_cmp(z, w1) == 0)
                goto outer_loop;
            /* (Step 4.7.4) */
            if (BN_is_one(z))
                goto composite;
        }
        /* At this point z = b^((w-1)/2) mod w */
        /* (Steps 4.8 - 4.9) x = z, z = x^2 mod w */
        if (!BN_copy(x, z) || !BN_mod_mul(z, x, x, w, ctx))
            goto err;
        /* (Step 4.10) */
        if (BN_is_one(z))
            goto composite;
        /* (Step 4.11) x = b^(w-1) mod w */
        if (!BN_copy(x, z))
            goto err;
composite:
        if (enhanced) {
            /* (Step 4.1.2) g = GCD(x-1, w) */
            if (!BN_sub_word(x, 1) || !BN_gcd(g, x, w, ctx))
                goto err;
            /* (Steps 4.1.3 - 4.1.4) */
            if (BN_is_one(g))
                *status = BN_PRIMETEST_COMPOSITE_NOT_POWER_OF_PRIME;
            else
                *status = BN_PRIMETEST_COMPOSITE_WITH_FACTOR;
        } else {
            *status = BN_PRIMETEST_COMPOSITE;
        }
        ret = 1;
        goto err;
outer_loop: ;
        /* (Step 4.1.5) */
        if (!BN_GENCB_call(cb, 1, i))
            goto err;
    }
    /* (Step 5) */
    *status = BN_PRIMETEST_PROBABLY_PRIME;
    ret = 1;
err:
    BN_clear(g);
    BN_clear(w1);
    BN_clear(w3);
    BN_clear(x);
    BN_clear(m);
    BN_clear(z);
    BN_clear(b);
    BN_CTX_end(ctx);
    BN_MONT_CTX_free(mont);
    return ret;
}
Exemplo n.º 27
0
void
tests(void)
{
#ifndef USING_WOLFSSL
	struct bitmap *b;
	BIGNUM *bn;
	size_t len;
	int i, j, k, n;
	u_char bbuf[1024], bnbuf[1024];
	int r;
#else
	struct bitmap *b;
	BIGNUM *bn;
#endif

	TEST_START("bitmap_new");
	b = bitmap_new();
	ASSERT_PTR_NE(b, NULL);
	bn = BN_new();
	ASSERT_PTR_NE(bn, NULL);
	TEST_DONE();

	TEST_START("bitmap_set_bit / bitmap_test_bit");
#ifndef USING_WOLFSSL
	for (i = -1; i < NTESTS; i++) {
		for (j = -1; j < NTESTS; j++) {
			for (k = -1; k < NTESTS; k++) {
				bitmap_zero(b);
	/* wolfSSL does not have support for BN_clear at this time */
				BN_clear(bn);
				test_subtest_info("set %d/%d/%d", i, j, k);
				/* Set bits */
				if (i >= 0) {
					ASSERT_INT_EQ(bitmap_set_bit(b, i), 0);
					ASSERT_INT_EQ(BN_set_bit(bn, i), 1);
				}
				if (j >= 0) {
					ASSERT_INT_EQ(bitmap_set_bit(b, j), 0);
					ASSERT_INT_EQ(BN_set_bit(bn, j), 1);
				}
				if (k >= 0) {
					ASSERT_INT_EQ(bitmap_set_bit(b, k), 0);
					ASSERT_INT_EQ(BN_set_bit(bn, k), 1);
				}

				/* Check perfect match between bitmap and bn */
				test_subtest_info("match %d/%d/%d", i, j, k);
				for (n = 0; n < NTESTS; n++) {
					ASSERT_INT_EQ(BN_is_bit_set(bn, n),
					    bitmap_test_bit(b, n));
				}

				/* Test length calculations */
				test_subtest_info("length %d/%d/%d", i, j, k);
				ASSERT_INT_EQ(BN_num_bits(bn),
				    (int)bitmap_nbits(b));
				ASSERT_INT_EQ(BN_num_bytes(bn),
				    (int)bitmap_nbytes(b));

				/* Test serialisation */
				test_subtest_info("serialise %d/%d/%d",
				    i, j, k);
				len = bitmap_nbytes(b);
				memset(bbuf, 0xfc, sizeof(bbuf));
				ASSERT_INT_EQ(bitmap_to_string(b, bbuf,
				    sizeof(bbuf)), 0);
				for (n = len; n < (int)sizeof(bbuf); n++)
					ASSERT_U8_EQ(bbuf[n], 0xfc);
				r = BN_bn2bin(bn, bnbuf);
				ASSERT_INT_GE(r, 0);
				ASSERT_INT_EQ(r, (int)len);
				ASSERT_MEM_EQ(bbuf, bnbuf, len);

				/* Test deserialisation */
				test_subtest_info("deserialise %d/%d/%d",
				    i, j, k);
				bitmap_zero(b);
				ASSERT_INT_EQ(bitmap_from_string(b, bnbuf,
				    len), 0);
				for (n = 0; n < NTESTS; n++) {
					ASSERT_INT_EQ(BN_is_bit_set(bn, n),
					    bitmap_test_bit(b, n));
				}

				/* Test clearing bits */
				test_subtest_info("clear %d/%d/%d",
				    i, j, k);
				for (n = 0; n < NTESTS; n++) {
					ASSERT_INT_EQ(bitmap_set_bit(b, n), 0);
					ASSERT_INT_EQ(BN_set_bit(bn, n), 1);
				}
				if (i >= 0) {
					bitmap_clear_bit(b, i);
	/* wolfSSL does not have support for BN_clear_bit at this time */
					BN_clear_bit(bn, i);
				}
				if (j >= 0) {
					bitmap_clear_bit(b, j);
	/* wolfSSL does not have support for BN_clear_bit at this time */
					BN_clear_bit(bn, j);
				}
				if (k >= 0) {
					bitmap_clear_bit(b, k);
	/* wolfSSL does not have support for BN_clear_bit at this time */
					BN_clear_bit(bn, k);
				}
				for (n = 0; n < NTESTS; n++) {
					ASSERT_INT_EQ(BN_is_bit_set(bn, n),
					    bitmap_test_bit(b, n));
				}
			}
		}
	}
#endif /* USING_WOLFSSL */
	bitmap_free(b);
	BN_free(bn);
	TEST_DONE();
}
Exemplo n.º 28
0
 BigNum (BigNum const& other)
     : num (BN_new ())
 {
     if (BN_copy (num, other.num) == nullptr)
         BN_clear (num);
 }