Пример #1
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 );
}
Пример #2
0
BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w)
  {
  BN_ULONG ret = 0;
  int i, j;

  bn_check_top(a);
  w &= BN_MASK2;

  if (!w)
    /* actually this an error (division by zero) */
    return (BN_ULONG)-1;
  if (a->top == 0)
    return 0;

  /* normalize input (so bn_div_words doesn't complain) */
  j = BN_BITS2 - BN_num_bits_word(w);
  w <<= j;
  if (!BN_lshift(a, a, j))
    return (BN_ULONG)-1;

  for (i=a->top-1; i>=0; i--)
    {
    BN_ULONG l,d;
    
    l=a->d[i];
    d=bn_div_words(ret,l,w);
    ret=(l-((d*w)&BN_MASK2))&BN_MASK2;
    a->d[i]=d;
    }
  if ((a->top > 0) && (a->d[a->top-1] == 0))
    a->top--;
  ret >>= j;
  bn_check_top(a);
  return(ret);
  }
Пример #3
0
static int
long_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype,
    const ASN1_ITEM *it)
{
	long ltmp;
	unsigned long utmp;
	int clen, pad, i;
	/* this exists to bypass broken gcc optimization */
	char *cp = (char *)pval;

	/* use memcpy, because we may not be long aligned */
	memcpy(&ltmp, cp, sizeof(long));

	if (ltmp == it->size)
		return -1;
	/* Convert the long to positive: we subtract one if negative so
	 * we can cleanly handle the padding if only the MSB of the leading
	 * octet is set.
	 */
	if (ltmp < 0)
		utmp = -ltmp - 1;
	else
		utmp = ltmp;
	clen = BN_num_bits_word(utmp);
	/* If MSB of leading octet set we need to pad */
	if (!(clen & 0x7))
		pad = 1;
	else
		pad = 0;

	/* Convert number of bits to number of octets */
	clen = (clen + 7) >> 3;

	if (cont) {
		if (pad)
			*cont++ = (ltmp < 0) ? 0xff : 0;
		for (i = clen - 1; i >= 0; i--) {
			cont[i] = (unsigned char)(utmp & 0xff);
			if (ltmp < 0)
				cont[i] ^= 0xff;
			utmp >>= 8;
		}
	}
	return clen + pad;
}
Пример #4
0
/**
 * public static native int bitLength(int)
 */
static int NativeBN_bitLength(JNIEnv* env, jclass cls, BIGNUM* a) {
// We rely on: (BN_BITS2 == 32), i.e. BN_ULONG is unsigned int and has 4 bytes:
//
    if (!oneValidHandle(env, a)) return FALSE;
    bn_check_top(a);
    int intLen = a->top;
    if (intLen == 0) return 0;
    BN_ULONG* d = a->d;
    int i = intLen - 1;
    BN_ULONG msd = d[i]; // most significant digit
        if (a->neg) {
            // Handle negative values correctly:
            // i.e. decrement the msd if all other digits are 0:
            // while ((i > 0) && (d[i] != 0)) { i--; }
            do { i--; } while (!((i < 0) || (d[i] != 0)));
            if (i < 0) msd--; // Only if all lower significant digits are 0 we decrement the most significant one.
        }
        return (intLen - 1) * 32 + BN_num_bits_word(msd);
}
Пример #5
0
int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
{
    int ret = 0;
    int top, al, bl;
    BIGNUM *rr;
#if defined(BN_MUL_COMBA) || defined(BN_RECURSION)
    int i;
#endif
#ifdef BN_RECURSION
    BIGNUM *t = NULL;
    int j = 0, k;
#endif

    bn_check_top(a);
    bn_check_top(b);
    bn_check_top(r);

    al = a->top;
    bl = b->top;

    if ((al == 0) || (bl == 0)) {
        BN_zero(r);
        return (1);
    }
    top = al + bl;

    BN_CTX_start(ctx);
    if ((r == a) || (r == b)) {
        if ((rr = BN_CTX_get(ctx)) == NULL)
            goto err;
    } else
        rr = r;

#if defined(BN_MUL_COMBA) || defined(BN_RECURSION)
    i = al - bl;
#endif
#ifdef BN_MUL_COMBA
    if (i == 0) {
# if 0
        if (al == 4) {
            if (bn_wexpand(rr, 8) == NULL)
                goto err;
            rr->top = 8;
            bn_mul_comba4(rr->d, a->d, b->d);
            goto end;
        }
# endif
        if (al == 8) {
            if (bn_wexpand(rr, 16) == NULL)
                goto err;
            rr->top = 16;
            bn_mul_comba8(rr->d, a->d, b->d);
            goto end;
        }
    }
#endif                          /* BN_MUL_COMBA */
#ifdef BN_RECURSION
    if ((al >= BN_MULL_SIZE_NORMAL) && (bl >= BN_MULL_SIZE_NORMAL)) {
        if (i >= -1 && i <= 1) {
            /*
             * Find out the power of two lower or equal to the longest of the
             * two numbers
             */
            if (i >= 0) {
                j = BN_num_bits_word((BN_ULONG)al);
            }
            if (i == -1) {
                j = BN_num_bits_word((BN_ULONG)bl);
            }
            j = 1 << (j - 1);
            assert(j <= al || j <= bl);
            k = j + j;
            t = BN_CTX_get(ctx);
            if (t == NULL)
                goto err;
            if (al > j || bl > j) {
                if (bn_wexpand(t, k * 4) == NULL)
                    goto err;
                if (bn_wexpand(rr, k * 4) == NULL)
                    goto err;
                bn_mul_part_recursive(rr->d, a->d, b->d,
                                      j, al - j, bl - j, t->d);
            } else {            /* al <= j || bl <= j */

                if (bn_wexpand(t, k * 2) == NULL)
                    goto err;
                if (bn_wexpand(rr, k * 2) == NULL)
                    goto err;
                bn_mul_recursive(rr->d, a->d, b->d, j, al - j, bl - j, t->d);
            }
            rr->top = top;
            goto end;
        }
# if 0
        if (i == 1 && !BN_get_flags(b, BN_FLG_STATIC_DATA)) {
            BIGNUM *tmp_bn = (BIGNUM *)b;
            if (bn_wexpand(tmp_bn, al) == NULL)
                goto err;
            tmp_bn->d[bl] = 0;
            bl++;
            i--;
        } else if (i == -1 && !BN_get_flags(a, BN_FLG_STATIC_DATA)) {
            BIGNUM *tmp_bn = (BIGNUM *)a;
            if (bn_wexpand(tmp_bn, bl) == NULL)
                goto err;
            tmp_bn->d[al] = 0;
            al++;
            i++;
        }
        if (i == 0) {
            /* symmetric and > 4 */
            /* 16 or larger */
            j = BN_num_bits_word((BN_ULONG)al);
            j = 1 << (j - 1);
            k = j + j;
            t = BN_CTX_get(ctx);
            if (al == j) {      /* exact multiple */
                if (bn_wexpand(t, k * 2) == NULL)
                    goto err;
                if (bn_wexpand(rr, k * 2) == NULL)
                    goto err;
                bn_mul_recursive(rr->d, a->d, b->d, al, t->d);
            } else {
                if (bn_wexpand(t, k * 4) == NULL)
                    goto err;
                if (bn_wexpand(rr, k * 4) == NULL)
                    goto err;
                bn_mul_part_recursive(rr->d, a->d, b->d, al - j, j, t->d);
            }
            rr->top = top;
            goto end;
        }
# endif
    }
#endif                          /* BN_RECURSION */
    if (bn_wexpand(rr, top) == NULL)
        goto err;
    rr->top = top;
    bn_mul_normal(rr->d, a->d, al, b->d, bl);

#if defined(BN_MUL_COMBA) || defined(BN_RECURSION)
 end:
#endif
    rr->neg = a->neg ^ b->neg;
    bn_correct_top(rr);
    if (r != rr && BN_copy(r, rr) == NULL)
        goto err;

    ret = 1;
 err:
    bn_check_top(r);
    BN_CTX_end(ctx);
    return (ret);
}
Пример #6
0
/* I've just gone over this and it is now %20 faster on x86 - eay - 27 Jun 96 */
int BN_sqr(BIGNUM *r, BIGNUM *a, BN_CTX *ctx)
	{
	int max,al;
	int ret = 0;
	BIGNUM *tmp,*rr;

#ifdef BN_COUNT
printf("BN_sqr %d * %d\n",a->top,a->top);
#endif
	bn_check_top(a);

	al=a->top;
	if (al <= 0)
		{
		r->top=0;
		return(1);
		}

	BN_CTX_start(ctx);
	rr=(a != r) ? r : BN_CTX_get(ctx);
	tmp=BN_CTX_get(ctx);
	if (tmp == NULL) goto err;

	max=(al+al);
	if (bn_wexpand(rr,max+1) == NULL) goto err;

	r->neg=0;
	if (al == 4)
		{
#ifndef BN_SQR_COMBA
		BN_ULONG t[8];
		bn_sqr_normal(rr->d,a->d,4,t);
#else
		bn_sqr_comba4(rr->d,a->d);
#endif
		}
	else if (al == 8)
		{
#ifndef BN_SQR_COMBA
		BN_ULONG t[16];
		bn_sqr_normal(rr->d,a->d,8,t);
#else
		bn_sqr_comba8(rr->d,a->d);
#endif
		}
	else 
		{
#if defined(BN_RECURSION)
		if (al < BN_SQR_RECURSIVE_SIZE_NORMAL)
			{
			BN_ULONG t[BN_SQR_RECURSIVE_SIZE_NORMAL*2];
			bn_sqr_normal(rr->d,a->d,al,t);
			}
		else
			{
			int j,k;

			j=BN_num_bits_word((BN_ULONG)al);
			j=1<<(j-1);
			k=j+j;
			if (al == j)
				{
				if (bn_wexpand(a,k*2) == NULL) goto err;
				if (bn_wexpand(tmp,k*2) == NULL) goto err;
				bn_sqr_recursive(rr->d,a->d,al,tmp->d);
				}
			else
				{
				if (bn_wexpand(tmp,max) == NULL) goto err;
				bn_sqr_normal(rr->d,a->d,al,tmp->d);
				}
			}
#else
		if (bn_wexpand(tmp,max) == NULL) goto err;
		bn_sqr_normal(rr->d,a->d,al,tmp->d);
#endif
		}

	rr->top=max;
	if ((max > 0) && (rr->d[max-1] == 0)) rr->top--;
	if (rr != r) BN_copy(r,rr);
	ret = 1;
 err:
	BN_CTX_end(ctx);
	return(ret);
	}
Пример #7
0
/* I've just gone over this and it is now %20 faster on x86 - eay - 27 Jun 96 */
int BN_sqr(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)
	{
	int max,al;
	int ret = 0;
	BIGNUM *tmp,*rr;

#ifdef BN_COUNT
	fprintf(stderr,"BN_sqr %d * %d\n",a->top,a->top);
#endif
	bn_check_top(a);

	al=a->top;
	if (al <= 0)
		{
		r->top=0;
		return 1;
		}

	BN_CTX_start(ctx);
	rr=(a != r) ? r : BN_CTX_get(ctx);
	tmp=BN_CTX_get(ctx);
	if (!rr || !tmp) goto err;

	max = 2 * al; /* Non-zero (from above) */
	if (bn_wexpand(rr,max) == NULL) goto err;

	if (al == 4)
		{
#ifndef BN_SQR_COMBA
		BN_ULONG t[8];
		bn_sqr_normal(rr->d,a->d,4,t);
#else
		bn_sqr_comba4(rr->d,a->d);
#endif
		}
	else if (al == 8)
		{
#ifndef BN_SQR_COMBA
		BN_ULONG t[16];
		bn_sqr_normal(rr->d,a->d,8,t);
#else
		bn_sqr_comba8(rr->d,a->d);
#endif
		}
	else 
		{
#if defined(BN_RECURSION)
		if (al < BN_SQR_RECURSIVE_SIZE_NORMAL)
			{
			BN_ULONG t[BN_SQR_RECURSIVE_SIZE_NORMAL*2];
			bn_sqr_normal(rr->d,a->d,al,t);
			}
		else
			{
			int j,k;

			j=BN_num_bits_word((BN_ULONG)al);
			j=1<<(j-1);
			k=j+j;
			if (al == j)
				{
				if (bn_wexpand(tmp,k*2) == NULL) goto err;
				bn_sqr_recursive(rr->d,a->d,al,tmp->d);
				}
			else
				{
				if (bn_wexpand(tmp,max) == NULL) goto err;
				bn_sqr_normal(rr->d,a->d,al,tmp->d);
				}
			}
#else
		if (bn_wexpand(tmp,max) == NULL) goto err;
		bn_sqr_normal(rr->d,a->d,al,tmp->d);
#endif
		}

	rr->neg=0;
	/* If the most-significant half of the top word of 'a' is zero, then
	 * the square of 'a' will max-1 words. */
	if(a->d[al - 1] == (a->d[al - 1] & BN_MASK2l))
		rr->top = max - 1;
	else
		rr->top = max;
	if (rr != r) BN_copy(r,rr);
	ret = 1;
 err:
	bn_check_top(rr);
	bn_check_top(tmp);
	BN_CTX_end(ctx);
	return(ret);
	}
Пример #8
0
int BN_sqr(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx) {
  int max, al;
  int ret = 0;
  BIGNUM *tmp, *rr;

  al = a->top;
  if (al <= 0) {
    r->top = 0;
    r->neg = 0;
    return 1;
  }

  BN_CTX_start(ctx);
  rr = (a != r) ? r : BN_CTX_get(ctx);
  tmp = BN_CTX_get(ctx);
  if (!rr || !tmp) {
    goto err;
  }

  max = 2 * al; /* Non-zero (from above) */
  if (bn_wexpand(rr, max) == NULL) {
    goto err;
  }

  if (al == 4) {
    bn_sqr_comba4(rr->d, a->d);
  } else if (al == 8) {
    bn_sqr_comba8(rr->d, a->d);
  } else {
    if (al < BN_SQR_RECURSIVE_SIZE_NORMAL) {
      BN_ULONG t[BN_SQR_RECURSIVE_SIZE_NORMAL * 2];
      bn_sqr_normal(rr->d, a->d, al, t);
    } else {
      int j, k;

      j = BN_num_bits_word((BN_ULONG)al);
      j = 1 << (j - 1);
      k = j + j;
      if (al == j) {
        if (bn_wexpand(tmp, k * 2) == NULL) {
          goto err;
        }
        bn_sqr_recursive(rr->d, a->d, al, tmp->d);
      } else {
        if (bn_wexpand(tmp, max) == NULL) {
          goto err;
        }
        bn_sqr_normal(rr->d, a->d, al, tmp->d);
      }
    }
  }

  rr->neg = 0;
  /* If the most-significant half of the top word of 'a' is zero, then
   * the square of 'a' will max-1 words. */
  if (a->d[al - 1] == (a->d[al - 1] & BN_MASK2l)) {
    rr->top = max - 1;
  } else {
    rr->top = max;
  }

  if (rr != r) {
    BN_copy(r, rr);
  }
  ret = 1;

err:
  BN_CTX_end(ctx);
  return ret;
}
Пример #9
0
int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) {
  int ret = 0;
  int top, al, bl;
  BIGNUM *rr;
  int i;
  BIGNUM *t = NULL;
  int j = 0, k;

  al = a->top;
  bl = b->top;

  if ((al == 0) || (bl == 0)) {
    BN_zero(r);
    return 1;
  }
  top = al + bl;

  BN_CTX_start(ctx);
  if ((r == a) || (r == b)) {
    if ((rr = BN_CTX_get(ctx)) == NULL) {
      goto err;
    }
  } else {
    rr = r;
  }
  rr->neg = a->neg ^ b->neg;

  i = al - bl;
  if (i == 0) {
    if (al == 8) {
      if (bn_wexpand(rr, 16) == NULL) {
        goto err;
      }
      rr->top = 16;
      bn_mul_comba8(rr->d, a->d, b->d);
      goto end;
    }
  }

  if ((al >= BN_MULL_SIZE_NORMAL) && (bl >= BN_MULL_SIZE_NORMAL)) {
    if (i >= -1 && i <= 1) {
      /* Find out the power of two lower or equal
         to the longest of the two numbers */
      if (i >= 0) {
        j = BN_num_bits_word((BN_ULONG)al);
      }
      if (i == -1) {
        j = BN_num_bits_word((BN_ULONG)bl);
      }
      j = 1 << (j - 1);
      assert(j <= al || j <= bl);
      k = j + j;
      t = BN_CTX_get(ctx);
      if (t == NULL) {
        goto err;
      }
      if (al > j || bl > j) {
        if (bn_wexpand(t, k * 4) == NULL) {
          goto err;
        }
        if (bn_wexpand(rr, k * 4) == NULL) {
          goto err;
        }
        bn_mul_part_recursive(rr->d, a->d, b->d, j, al - j, bl - j, t->d);
      } else {
        /* al <= j || bl <= j */
        if (bn_wexpand(t, k * 2) == NULL) {
          goto err;
        }
        if (bn_wexpand(rr, k * 2) == NULL) {
          goto err;
        }
        bn_mul_recursive(rr->d, a->d, b->d, j, al - j, bl - j, t->d);
      }
      rr->top = top;
      goto end;
    }
  }

  if (bn_wexpand(rr, top) == NULL) {
    goto err;
  }
  rr->top = top;
  bn_mul_normal(rr->d, a->d, al, b->d, bl);

end:
  bn_correct_top(rr);
  if (r != rr) {
    BN_copy(r, rr);
  }
  ret = 1;

err:
  BN_CTX_end(ctx);
  return ret;
}
Пример #10
0
int bn_sqr_fixed_top(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)
{
    int max, al;
    int ret = 0;
    BIGNUM *tmp, *rr;

    bn_check_top(a);

    al = a->top;
    if (al <= 0) {
        r->top = 0;
        r->neg = 0;
        return 1;
    }

    BN_CTX_start(ctx);
    rr = (a != r) ? r : BN_CTX_get(ctx);
    tmp = BN_CTX_get(ctx);
    if (rr == NULL || tmp == NULL)
        goto err;

    max = 2 * al;               /* Non-zero (from above) */
    if (bn_wexpand(rr, max) == NULL)
        goto err;

    if (al == 4) {
#ifndef BN_SQR_COMBA
        BN_ULONG t[8];
        bn_sqr_normal(rr->d, a->d, 4, t);
#else
        bn_sqr_comba4(rr->d, a->d);
#endif
    } else if (al == 8) {
#ifndef BN_SQR_COMBA
        BN_ULONG t[16];
        bn_sqr_normal(rr->d, a->d, 8, t);
#else
        bn_sqr_comba8(rr->d, a->d);
#endif
    } else {
#if defined(BN_RECURSION)
        if (al < BN_SQR_RECURSIVE_SIZE_NORMAL) {
            BN_ULONG t[BN_SQR_RECURSIVE_SIZE_NORMAL * 2];
            bn_sqr_normal(rr->d, a->d, al, t);
        } else {
            int j, k;

            j = BN_num_bits_word((BN_ULONG)al);
            j = 1 << (j - 1);
            k = j + j;
            if (al == j) {
                if (bn_wexpand(tmp, k * 2) == NULL)
                    goto err;
                bn_sqr_recursive(rr->d, a->d, al, tmp->d);
            } else {
                if (bn_wexpand(tmp, max) == NULL)
                    goto err;
                bn_sqr_normal(rr->d, a->d, al, tmp->d);
            }
        }
#else
        if (bn_wexpand(tmp, max) == NULL)
            goto err;
        bn_sqr_normal(rr->d, a->d, al, tmp->d);
#endif
    }

    rr->neg = 0;
    rr->top = max;
    rr->flags |= BN_FLG_FIXED_TOP;
    if (r != rr && BN_copy(r, rr) == NULL)
        goto err;

    ret = 1;
 err:
    bn_check_top(rr);
    bn_check_top(tmp);
    BN_CTX_end(ctx);
    return ret;
}
Пример #11
0
int bn_mul_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
{
    int ret = 0;
    int top, al, bl;
    BIGNUM *rr;
#if defined(BN_MUL_COMBA) || defined(BN_RECURSION)
    int i;
#endif
#ifdef BN_RECURSION
    BIGNUM *t = NULL;
    int j = 0, k;
#endif

    bn_check_top(a);
    bn_check_top(b);
    bn_check_top(r);

    al = a->top;
    bl = b->top;

    if ((al == 0) || (bl == 0)) {
        BN_zero(r);
        return 1;
    }
    top = al + bl;

    BN_CTX_start(ctx);
    if ((r == a) || (r == b)) {
        if ((rr = BN_CTX_get(ctx)) == NULL)
            goto err;
    } else
        rr = r;

#if defined(BN_MUL_COMBA) || defined(BN_RECURSION)
    i = al - bl;
#endif
#ifdef BN_MUL_COMBA
    if (i == 0) {
# if 0
        if (al == 4) {
            if (bn_wexpand(rr, 8) == NULL)
                goto err;
            rr->top = 8;
            bn_mul_comba4(rr->d, a->d, b->d);
            goto end;
        }
# endif
        if (al == 8) {
            if (bn_wexpand(rr, 16) == NULL)
                goto err;
            rr->top = 16;
            bn_mul_comba8(rr->d, a->d, b->d);
            goto end;
        }
    }
#endif                          /* BN_MUL_COMBA */
#ifdef BN_RECURSION
    if ((al >= BN_MULL_SIZE_NORMAL) && (bl >= BN_MULL_SIZE_NORMAL)) {
        if (i >= -1 && i <= 1) {
            /*
             * Find out the power of two lower or equal to the longest of the
             * two numbers
             */
            if (i >= 0) {
                j = BN_num_bits_word((BN_ULONG)al);
            }
            if (i == -1) {
                j = BN_num_bits_word((BN_ULONG)bl);
            }
            j = 1 << (j - 1);
            assert(j <= al || j <= bl);
            k = j + j;
            t = BN_CTX_get(ctx);
            if (t == NULL)
                goto err;
            if (al > j || bl > j) {
                if (bn_wexpand(t, k * 4) == NULL)
                    goto err;
                if (bn_wexpand(rr, k * 4) == NULL)
                    goto err;
                bn_mul_part_recursive(rr->d, a->d, b->d,
                                      j, al - j, bl - j, t->d);
            } else {            /* al <= j || bl <= j */

                if (bn_wexpand(t, k * 2) == NULL)
                    goto err;
                if (bn_wexpand(rr, k * 2) == NULL)
                    goto err;
                bn_mul_recursive(rr->d, a->d, b->d, j, al - j, bl - j, t->d);
            }
            rr->top = top;
            goto end;
        }
    }
#endif                          /* BN_RECURSION */
    if (bn_wexpand(rr, top) == NULL)
        goto err;
    rr->top = top;
    bn_mul_normal(rr->d, a->d, al, b->d, bl);

#if defined(BN_MUL_COMBA) || defined(BN_RECURSION)
 end:
#endif
    rr->neg = a->neg ^ b->neg;
    rr->flags |= BN_FLG_FIXED_TOP;
    if (r != rr && BN_copy(r, rr) == NULL)
        goto err;

    ret = 1;
 err:
    bn_check_top(r);
    BN_CTX_end(ctx);
    return ret;
}
Пример #12
0
int BN_mul(BIGNUM *r, BIGNUM *a, BIGNUM *b, BN_CTX *ctx)
	{
	int top,al,bl;
	BIGNUM *rr;
	int ret = 0;
#if defined(BN_MUL_COMBA) || defined(BN_RECURSION)
	int i;
#endif
#ifdef BN_RECURSION
	BIGNUM *t;
	int j,k;
#endif

#ifdef BN_COUNT
	printf("BN_mul %d * %d\n",a->top,b->top);
#endif

	bn_check_top(a);
	bn_check_top(b);
	bn_check_top(r);

	al=a->top;
	bl=b->top;

	if ((al == 0) || (bl == 0))
		{
		BN_zero(r);
		return(1);
		}
	top=al+bl;

	BN_CTX_start(ctx);
	if ((r == a) || (r == b))
		{
		if ((rr = BN_CTX_get(ctx)) == NULL) goto err;
		}
	else
		rr = r;
	rr->neg=a->neg^b->neg;

#if defined(BN_MUL_COMBA) || defined(BN_RECURSION)
	i = al-bl;
#endif
#ifdef BN_MUL_COMBA
	if (i == 0)
		{
# if 0
		if (al == 4)
			{
			if (bn_wexpand(rr,8) == NULL) goto err;
			rr->top=8;
			bn_mul_comba4(rr->d,a->d,b->d);
			goto end;
			}
# endif
		if (al == 8)
			{
			if (bn_wexpand(rr,16) == NULL) goto err;
			rr->top=16;
			bn_mul_comba8(rr->d,a->d,b->d);
			goto end;
			}
		}
#endif /* BN_MUL_COMBA */
#ifdef BN_RECURSION
	if ((al >= BN_MULL_SIZE_NORMAL) && (bl >= BN_MULL_SIZE_NORMAL))
		{
		if (i == 1 && !BN_get_flags(b,BN_FLG_STATIC_DATA))
			{
			if (bn_wexpand(b,al) == NULL) goto err;
			b->d[bl]=0;
			bl++;
			i--;
			}
		else if (i == -1 && !BN_get_flags(a,BN_FLG_STATIC_DATA))
			{
			if (bn_wexpand(a,bl) == NULL) goto err;
			a->d[al]=0;
			al++;
			i++;
			}
		if (i == 0)
			{
			/* symmetric and > 4 */
			/* 16 or larger */
			j=BN_num_bits_word((BN_ULONG)al);
			j=1<<(j-1);
			k=j+j;
			t = BN_CTX_get(ctx);
			if (al == j) /* exact multiple */
				{
				if (bn_wexpand(t,k*2) == NULL) goto err;
				if (bn_wexpand(rr,k*2) == NULL) goto err;
				bn_mul_recursive(rr->d,a->d,b->d,al,t->d);
				}
			else
				{
				if (bn_wexpand(a,k) == NULL) goto err;
				if (bn_wexpand(b,k) == NULL) goto err;
				if (bn_wexpand(t,k*4) == NULL) goto err;
				if (bn_wexpand(rr,k*4) == NULL) goto err;
				for (i=a->top; i<k; i++)
					a->d[i]=0;
				for (i=b->top; i<k; i++)
					b->d[i]=0;
				bn_mul_part_recursive(rr->d,a->d,b->d,al-j,j,t->d);
				}
			rr->top=top;
			goto end;
			}
		}
#endif /* BN_RECURSION */
	if (bn_wexpand(rr,top) == NULL) goto err;
	rr->top=top;
	bn_mul_normal(rr->d,a->d,al,b->d,bl);

#if defined(BN_MUL_COMBA) || defined(BN_RECURSION)
end:
#endif
	bn_fix_top(rr);
	if (r != rr) BN_copy(r,rr);
	ret=1;
err:
	BN_CTX_end(ctx);
	return(ret);
	}
Пример #13
0
int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
{
    int ret = 0;
    int top, al, bl;
    BIGNUM *rr;
#if defined(BN_MUL_COMBA) || defined(BN_RECURSION)
    int i;
#endif
#ifdef BN_RECURSION
    BIGNUM *t = NULL;
    int j = 0, k;
#endif

#ifdef BN_COUNT
    fprintf(stderr, "BN_mul %d * %d\n", a->top, b->top);
#endif

    bn_check_top(a);
    bn_check_top(b);
    bn_check_top(r);

    al = a->top;
    bl = b->top;

    if ((al == 0) || (bl == 0)) {
        BN_zero(r);
        return (1);
    }
    top = al + bl;

    BN_CTX_start(ctx);
    if ((r == a) || (r == b)) {
        if ((rr = BN_CTX_get(ctx)) == NULL)
            goto err;
    } else
/* Changes for cryptlib - pcg */
		{
		/* Usually we can set:
			rr = r;
		   but in the cases where t gets large (see the check further down
		   for overflow due to k * 2 / k * 4) the value of rr needs to be
		   large as well.  We can't predict in advance when this will occur 
		   so we have to use an extended-size bignum for rr in all cases */
		rr = ( BIGNUM * ) BN_CTX_get_ext( ctx, BIGNUM_EXT_MUL1 );
		if( rr == NULL )
			goto err;
		}
/* End changes for cryptlib - pcg */
    rr->neg = a->neg ^ b->neg;

#if defined(BN_MUL_COMBA) || defined(BN_RECURSION)
    i = al - bl;
#endif
#ifdef BN_MUL_COMBA
    if (i == 0) {
# if 0
        if (al == 4) {
            if (bn_wexpand(rr, 8) == NULL)
                goto err;
            rr->top = 8;
            bn_mul_comba4(rr->d, a->d, b->d);
            goto end;
        }
# endif
        if (al == 8) {
            if (bn_wexpand(rr, 16) == NULL)
                goto err;
            rr->top = 16;
            bn_mul_comba8(rr->d, a->d, b->d);
            goto end;
        }
    }
#endif                          /* BN_MUL_COMBA */
#ifdef BN_RECURSION
    if ((al >= BN_MULL_SIZE_NORMAL) && (bl >= BN_MULL_SIZE_NORMAL)) {
        if (i >= -1 && i <= 1) {
            /*
             * Find out the power of two lower or equal to the longest of the
             * two numbers
             */
            if (i >= 0) {
                j = BN_num_bits_word((BN_ULONG)al);
            }
            if (i == -1) {
                j = BN_num_bits_word((BN_ULONG)bl);
            }
            j = 1 << (j - 1);
            assert(j <= al || j <= bl);
            k = j + j;
/* Changes for cryptlib - pcg */
			if( ( k * 2 > BIGNUM_ALLOC_WORDS ) || \
				( ( al > j || bl > j ) && ( k * 4 > BIGNUM_ALLOC_WORDS ) ) )
				{
				/* We're about to expand the temporary bignum that we're 
				   using to an enormous size, get a special extended-size 
				   bignum that won't result in a storage size-check error
				   when used */
				t = BN_CTX_get_ext( ctx, BIGNUM_EXT_MUL2 );
				}
			else
				t = BN_CTX_get(ctx);
/* End changes for cryptlib - pcg */
            if (t == NULL)
                goto err;
            if (al > j || bl > j) {
                if (bn_wexpand(t, k * 4) == NULL)
                    goto err;
                if (bn_wexpand(rr, k * 4) == NULL)
                    goto err;
                bn_mul_part_recursive(rr->d, a->d, b->d,
                                      j, al - j, bl - j, t->d);
            } else {            /* al <= j || bl <= j */

                if (bn_wexpand(t, k * 2) == NULL)
                    goto err;
                if (bn_wexpand(rr, k * 2) == NULL)
                    goto err;
                bn_mul_recursive(rr->d, a->d, b->d, j, al - j, bl - j, t->d);
            }
            rr->top = top;
            goto end;
        }
# if 0
        if (i == 1 && !BN_get_flags(b, BN_FLG_STATIC_DATA)) {
            BIGNUM *tmp_bn = (BIGNUM *)b;
            if (bn_wexpand(tmp_bn, al) == NULL)
                goto err;
            tmp_bn->d[bl] = 0;
            bl++;
            i--;
        } else if (i == -1 && !BN_get_flags(a, BN_FLG_STATIC_DATA)) {
            BIGNUM *tmp_bn = (BIGNUM *)a;
            if (bn_wexpand(tmp_bn, bl) == NULL)
                goto err;
            tmp_bn->d[al] = 0;
            al++;
            i++;
        }
        if (i == 0) {
            /* symmetric and > 4 */
            /* 16 or larger */
            j = BN_num_bits_word((BN_ULONG)al);
            j = 1 << (j - 1);
            k = j + j;
            t = BN_CTX_get(ctx);
            if (al == j) {      /* exact multiple */
                if (bn_wexpand(t, k * 2) == NULL)
                    goto err;
                if (bn_wexpand(rr, k * 2) == NULL)
                    goto err;
                bn_mul_recursive(rr->d, a->d, b->d, al, t->d);
            } else {
                if (bn_wexpand(t, k * 4) == NULL)
                    goto err;
                if (bn_wexpand(rr, k * 4) == NULL)
                    goto err;
                bn_mul_part_recursive(rr->d, a->d, b->d, al - j, j, t->d);
            }
            rr->top = top;
            goto end;
        }
# endif
    }
#endif                          /* BN_RECURSION */
    if (bn_wexpand(rr, top) == NULL)
        goto err;
    rr->top = top;
    bn_mul_normal(rr->d, a->d, al, b->d, bl);

#if defined(BN_MUL_COMBA) || defined(BN_RECURSION)
 end:
#endif
    bn_correct_top(rr);
    if (r != rr)
        BN_copy(r, rr);
    ret = 1;
 err:
    bn_check_top(r);
	BN_CTX_end_ext( ctx, BIGNUM_EXT_MUL1 );			/* pcg */
    return (ret);
}
Пример #14
0
// Checks if the given password is valid
bool Tester::check(const Memblock &mblock)
{
	const String2Key &s2k = m_key.string2Key();
	int32_t tmp = 0;

	// Generate key from password
	s2k.generateKey(mblock, m_keydata, m_keySize);

	// Decrypt first data block in order to check the first two bits of
	// the MPI. If they are correct, there's a good chance that the
	// password is correct, too.
#if 1
	memcpy(m_ivec, s2k.ivec(), m_blockSize);
	if (m_key.version() < 4) {
		// Prior to V4, MPI lengths are unencrypted.
		memcpy(m_out, m_in, 2);
		m_key.decrypt(&m_in[2], &m_out[2], m_blockSize, m_keydata, m_keySize, m_ivec, &tmp);
	} else {
		m_key.decrypt(m_in, m_out, m_blockSize, m_keydata, m_keySize, m_ivec, &tmp);
	}

	uint32_t num_bits = ((m_out[0] << 8) | m_out[1]);
	if (num_bits < MIN_BN_BITS || num_bits > m_bits ||
	    (num_bits % 8 != BN_num_bits_word(m_out[2]) % 8))
	{
		return false;
	}
#endif

	// Decrypt all data
	memcpy(m_ivec, s2k.ivec(), m_blockSize);
	if (m_key.version() < 4) {
		// V3 keys are RSA only according to [5.5.3].
		if (CryptUtils::PKA_RSA_ENCSIGN != m_key.algorithm()) {
			throw Utils::strprintf("Unexpected V3 algorithm: %d",
				m_key.algorithm());
		}

		// Prior to V4, the four RSA MPIs were encrypted separately.
		uint32_t ofs = 0;
		for (uint32_t i = 0; i != 4; ++i) {
			memcpy(&m_out[ofs], &m_in[ofs], 2);
			uint32_t len = (((m_out[ofs] << 8) | m_out[1 + ofs]) + 7) / 8;
			ofs += 2;

			if (m_datalen < ofs + len) {
				throw "Insufficient data length";
			}
			tmp = 0;
			m_key.decrypt(&m_in[ofs], &m_out[ofs], len, m_keydata, m_keySize, m_ivec, &tmp);
			ofs += len;
		}

		// Copy checksum.
		memcpy(&m_out[ofs], &m_in[ofs], 2);
		ofs += 2;
		if (ofs != m_datalen) {
			throw "Data length mismatch";
		}
	} else {
		tmp = 0;
		m_key.decrypt(m_in, m_out, m_datalen, m_keydata, m_keySize, m_ivec, &tmp);
	}

	// Verify
	bool checksumOk = false;
	switch (s2k.usage()) {
		case 254: {
			uint8_t checksum[SHA_DIGEST_LENGTH];
			pgpry_SHA_CTX ctx;
			pgpry_SHA1_Init(&ctx);
			pgpry_SHA1_Update(&ctx, m_out, m_datalen - SHA_DIGEST_LENGTH);
			pgpry_SHA1_Final(checksum, &ctx);
			if (memcmp(checksum, m_out + m_datalen - SHA_DIGEST_LENGTH, SHA_DIGEST_LENGTH) == 0) {
				checksumOk = true;
			}
		} break;

		default: {
			uint16_t sum = 0;
			for (uint32_t i = 0; i < m_datalen - 2; i++) {
				sum += m_out[i];
			}
			if (sum == ((m_out[m_datalen - 2] << 8) | m_out[m_datalen - 1])) {
				checksumOk = true;
			}
		} break;
	}

	// If the checksum is ok, verify the secret key equations.
	return checksumOk && m_key.verify(m_out, m_datalen - 2);
}
Пример #15
0
// bn_mul_impl implements |BN_mul| and |bn_mul_consttime|. Note this function
// breaks |BIGNUM| invariants and may return a negative zero. This is handled by
// the callers.
static int bn_mul_impl(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
                       BN_CTX *ctx) {
  int al = a->width;
  int bl = b->width;
  if (al == 0 || bl == 0) {
    BN_zero(r);
    return 1;
  }

  int ret = 0;
  BIGNUM *rr;
  BN_CTX_start(ctx);
  if (r == a || r == b) {
    rr = BN_CTX_get(ctx);
    if (rr == NULL) {
      goto err;
    }
  } else {
    rr = r;
  }
  rr->neg = a->neg ^ b->neg;

  int i = al - bl;
  if (i == 0) {
    if (al == 8) {
      if (!bn_wexpand(rr, 16)) {
        goto err;
      }
      rr->width = 16;
      bn_mul_comba8(rr->d, a->d, b->d);
      goto end;
    }
  }

  int top = al + bl;
  static const int kMulNormalSize = 16;
  if (al >= kMulNormalSize && bl >= kMulNormalSize) {
    if (-1 <= i && i <= 1) {
      // Find the larger power of two less than or equal to the larger length.
      int j;
      if (i >= 0) {
        j = BN_num_bits_word((BN_ULONG)al);
      } else {
        j = BN_num_bits_word((BN_ULONG)bl);
      }
      j = 1 << (j - 1);
      assert(j <= al || j <= bl);
      BIGNUM *t = BN_CTX_get(ctx);
      if (t == NULL) {
        goto err;
      }
      if (al > j || bl > j) {
        // We know |al| and |bl| are at most one from each other, so if al > j,
        // bl >= j, and vice versa. Thus we can use |bn_mul_part_recursive|.
        assert(al >= j && bl >= j);
        if (!bn_wexpand(t, j * 8) ||
            !bn_wexpand(rr, j * 4)) {
          goto err;
        }
        bn_mul_part_recursive(rr->d, a->d, b->d, j, al - j, bl - j, t->d);
      } else {
        // al <= j && bl <= j. Additionally, we know j <= al or j <= bl, so one
        // of al - j or bl - j is zero. The other, by the bound on |i| above, is
        // zero or -1. Thus, we can use |bn_mul_recursive|.
        if (!bn_wexpand(t, j * 4) ||
            !bn_wexpand(rr, j * 2)) {
          goto err;
        }
        bn_mul_recursive(rr->d, a->d, b->d, j, al - j, bl - j, t->d);
      }
      rr->width = top;
      goto end;
    }
  }

  if (!bn_wexpand(rr, top)) {
    goto err;
  }
  rr->width = top;
  bn_mul_normal(rr->d, a->d, al, b->d, bl);

end:
  if (r != rr && !BN_copy(r, rr)) {
    goto err;
  }
  ret = 1;

err:
  BN_CTX_end(ctx);
  return ret;
}