Beispiel #1
0
static int fdt_add_bignum(void *blob, int noffset, const char *prop_name,
			  BIGNUM *num, int num_bits)
{
	int nwords = num_bits / 32;
	int size;
	uint32_t *buf, *ptr;
	BIGNUM *tmp, *big2, *big32, *big2_32;
	BN_CTX *ctx;
	int ret;

	tmp = BN_new();
	big2 = BN_new();
	big32 = BN_new();
	big2_32 = BN_new();
	if (!tmp || !big2 || !big32 || !big2_32) {
		fprintf(stderr, "Out of memory (bignum)\n");
		return -ENOMEM;
	}
	ctx = BN_CTX_new();
	if (!tmp) {
		fprintf(stderr, "Out of memory (bignum context)\n");
		return -ENOMEM;
	}
	BN_set_word(big2, 2L);
	BN_set_word(big32, 32L);
	BN_exp(big2_32, big2, big32, ctx); /* B = 2^32 */

	size = nwords * sizeof(uint32_t);
	buf = malloc(size);
	if (!buf) {
		fprintf(stderr, "Out of memory (%d bytes)\n", size);
		return -ENOMEM;
	}

	/* Write out modulus as big endian array of integers */
	for (ptr = buf + nwords - 1; ptr >= buf; ptr--) {
		BN_mod(tmp, num, big2_32, ctx); /* n = N mod B */
		*ptr = cpu_to_fdt32(BN_get_word(tmp));
		BN_rshift(num, num, 32); /*  N = N/B */
	}

	/* We try signing with successively increasing size values, so this
	 * might fail several times */
	ret = fdt_setprop(blob, noffset, prop_name, buf, size);
	if (ret)
		return -FDT_ERR_NOSPACE;
	free(buf);
	BN_free(tmp);
	BN_free(big2);
	BN_free(big32);
	BN_free(big2_32);

	return ret;
}
static int fdt_add_bignum(void *blob, int noffset, const char *prop_name,
			  BIGNUM *num, int num_bits)
{
	int nwords = num_bits / 32;
	int size;
	uint32_t *buf, *ptr;
	BIGNUM *tmp, *big2, *big32, *big2_32;
	BN_CTX *ctx;
	int ret;

	tmp = BN_new();
	big2 = BN_new();
	big32 = BN_new();
	big2_32 = BN_new();
	if (!tmp || !big2 || !big32 || !big2_32) {
		fprintf(stderr, "Out of memory (bignum)\n");
		return -ENOMEM;
	}
	ctx = BN_CTX_new();
	if (!tmp) {
		fprintf(stderr, "Out of memory (bignum context)\n");
		return -ENOMEM;
	}
	BN_set_word(big2, 2L);
	BN_set_word(big32, 32L);
	BN_exp(big2_32, big2, big32, ctx); /* B = 2^32 */

	size = nwords * sizeof(uint32_t);
	buf = malloc(size);
	if (!buf) {
		fprintf(stderr, "Out of memory (%d bytes)\n", size);
		return -ENOMEM;
	}

	/* Write out modulus as big endian array of integers */
	for (ptr = buf + nwords - 1; ptr >= buf; ptr--) {
		BN_mod(tmp, num, big2_32, ctx); /* n = N mod B */
		*ptr = cpu_to_fdt32(BN_get_word(tmp));
		BN_rshift(num, num, 32); /*  N = N/B */
	}

	ret = fdt_setprop(blob, noffset, prop_name, buf, size);
	if (ret) {
		fprintf(stderr, "Failed to write public key to FIT\n");
		return -ENOSPC;
	}
	free(buf);
	BN_free(tmp);
	BN_free(big2);
	BN_free(big32);
	BN_free(big2_32);

	return ret;
}
Beispiel #3
0
static int probable_prime_dh(BIGNUM *rnd, int bits, const BIGNUM *add,
                             const BIGNUM *rem, BN_CTX *ctx) {
  int i, ret = 0;
  BIGNUM *t1;

  BN_CTX_start(ctx);
  if ((t1 = BN_CTX_get(ctx)) == NULL) {
    goto err;
  }

  if (!BN_rand(rnd, bits, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ODD)) {
    goto err;
  }

  // we need ((rnd-rem) % add) == 0

  if (!BN_mod(t1, rnd, add, ctx)) {
    goto err;
  }
  if (!BN_sub(rnd, rnd, t1)) {
    goto err;
  }
  if (rem == NULL) {
    if (!BN_add_word(rnd, 1)) {
      goto err;
    }
  } else {
    if (!BN_add(rnd, rnd, rem)) {
      goto err;
    }
  }
  // we now have a random number 'rand' to test.

loop:
  for (i = 1; i < NUMPRIMES; i++) {
    // check that rnd is a prime
    BN_ULONG mod = BN_mod_word(rnd, (BN_ULONG)primes[i]);
    if (mod == (BN_ULONG)-1) {
      goto err;
    }
    if (mod <= 1) {
      if (!BN_add(rnd, rnd, add)) {
        goto err;
      }
      goto loop;
    }
  }

  ret = 1;

err:
  BN_CTX_end(ctx);
  return ret;
}
Beispiel #4
0
/* calculate p-1 and q-1 */
void
rsa_generate_additional_parameters(RSA *rsa)
{
	BIGNUM *aux;
	BN_CTX *ctx;

	if ((aux = BN_new()) == NULL)
		fatal("rsa_generate_additional_parameters: BN_new failed");
	if ((ctx = BN_CTX_new()) == NULL)
		fatal("rsa_generate_additional_parameters: BN_CTX_new failed");

	if ((BN_sub(aux, rsa->q, BN_value_one()) == 0) ||
	    (BN_mod(rsa->dmq1, rsa->d, aux, ctx) == 0) ||
	    (BN_sub(aux, rsa->p, BN_value_one()) == 0) ||
	    (BN_mod(rsa->dmp1, rsa->d, aux, ctx) == 0))
		fatal("rsa_generate_additional_parameters: BN_sub/mod failed");

	BN_clear_free(aux);
	BN_CTX_free(ctx);
}
Beispiel #5
0
uint8_t sane_key(RSA *rsa) { // checks sanity of a RSA key (PKCS#1 v2.1)
    uint8_t sane = 1;

    BN_CTX *ctx = BN_CTX_new();
    BN_CTX_start(ctx);
    BIGNUM *p1     = BN_CTX_get(ctx), // p - 1
            *q1     = BN_CTX_get(ctx), // q - 1
             *chk    = BN_CTX_get(ctx), // storage to run checks with
              *gcd    = BN_CTX_get(ctx), // GCD(p - 1, q - 1)
               *lambda = BN_CTX_get(ctx); // LCM(p - 1, q - 1)

    BN_sub(p1, rsa->p, BN_value_one()); // p - 1
    BN_sub(q1, rsa->q, BN_value_one()); // q - 1
    BN_gcd(gcd, p1, q1, ctx);           // gcd(p - 1, q - 1)
    BN_lcm(lambda, p1, q1, gcd, ctx);   // lambda(n)

    BN_gcd(chk, lambda, rsa->e, ctx); // check if e is coprime to lambda(n)
    if(!BN_is_one(chk))
        sane = 0;

    // check if public exponent e is less than n - 1
    BN_sub(chk, rsa->e, rsa->n); // subtract n from e to avoid checking BN_is_zero
    if(!chk->neg)
        sane = 0;

    BN_mod_inverse(rsa->d, rsa->e, lambda, ctx);    // d
    BN_mod(rsa->dmp1, rsa->d, p1, ctx);             // d mod (p - 1)
    BN_mod(rsa->dmq1, rsa->d, q1, ctx);             // d mod (q - 1)
    BN_mod_inverse(rsa->iqmp, rsa->q, rsa->p, ctx); // q ^ -1 mod p
    BN_CTX_end(ctx);
    BN_CTX_free(ctx);

    // this is excessive but you're better off safe than (very) sorry
    // in theory this should never be true unless I made a mistake ;)
    if((RSA_check_key(rsa) != 1) && sane) {
        fprintf(stderr, "WARNING: Key looked okay, but OpenSSL says otherwise!\n");
        sane = 0;
    }

    return sane;
}
Beispiel #6
0
int BN_nnmod(BIGNUM *r, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx)
	{
	/* like BN_mod, but returns non-negative remainder
	 * (i.e.,  0 <= r < |d|  always holds) */

	if (!(BN_mod(r,m,d,ctx)))
		return 0;
	if (!r->neg)
		return 1;
	/* now   -|d| < r < 0,  so we have to set  r := r + |d| */
	return (d->neg ? BN_sub : BN_add)(r, r, d);
}
Beispiel #7
0
static int probable_prime_dh_safe(BIGNUM *p, int bits, const BIGNUM *padd,
	const BIGNUM *rem, BN_CTX *ctx)
	{
	int i,ret=0;
	BIGNUM *t1,*qadd,*q;

	bits--;
	BN_CTX_start(ctx);
	t1 = BN_CTX_get(ctx);
	q = BN_CTX_get(ctx);
	qadd = BN_CTX_get(ctx);
	if (qadd == NULL) goto err;

	if (!BN_rshift1(qadd,padd)) goto err;
		
	if (!BN_rand(q,bits,0,1)) goto err;

	/* we need ((rnd-rem) % add) == 0 */
	if (!BN_mod(t1,q,qadd,ctx)) goto err;
	if (!BN_sub(q,q,t1)) goto err;
	if (rem == NULL)
		{ if (!BN_add_word(q,1)) goto err; }
	else
		{
		if (!BN_rshift1(t1,rem)) goto err;
		if (!BN_add(q,q,t1)) goto err;
		}

	/* we now have a random number 'rand' to test. */
	if (!BN_lshift1(p,q)) goto err;
	if (!BN_add_word(p,1)) goto err;

loop:
	for (i=1; i<NUMPRIMES; i++)
		{
		/* check that p and q are prime */
		/* check that for p and q
		 * gcd(p-1,primes) == 1 (except for 2) */
		if ((BN_mod_word(p,(BN_ULONG)primes[i]) == 0) ||
			(BN_mod_word(q,(BN_ULONG)primes[i]) == 0))
			{
			if (!BN_add(p,p,padd)) goto err;
			if (!BN_add(q,q,qadd)) goto err;
			goto loop;
			}
		}
	ret=1;

err:
	BN_CTX_end(ctx);
	bn_check_top(p);
	return(ret);
	}
Beispiel #8
0
BOOL rsautil_quickimport(RSA *rsa, BIGNUM *e_value, BIGNUM *p_value, BIGNUM *q_value, OPTIONAL BIGNUM *n_value)
{
	BIGNUM *r0, *r1, *r2;
	BN_CTX *ctx;

	ctx = BN_CTX_new();
	BN_CTX_start(ctx);
	r0 = BN_CTX_get(ctx);
	r1 = BN_CTX_get(ctx);
	r2 = BN_CTX_get(ctx);

	rsa->n = BN_new();
	rsa->d = BN_new();
	rsa->e = BN_new();
	rsa->p = BN_new();
	rsa->q = BN_new();
	rsa->dmp1 = BN_new();
	rsa->dmq1 = BN_new();
	rsa->iqmp = BN_new();

	BN_copy(rsa->e, e_value);
	BN_copy(rsa->p, p_value);
	BN_copy(rsa->q, q_value);
	if(n_value)
		BN_copy(rsa->n, n_value);
	else
		BN_mul(rsa->n, rsa->p, rsa->q, ctx);
	BN_sub(r1, rsa->p, BN_value_one());
	BN_sub(r2, rsa->q, BN_value_one());
	BN_mul(r0, r1, r2, ctx);
	BN_mod_inverse(rsa->d, rsa->e, r0, ctx);
	BN_mod(rsa->dmp1, rsa->d, r1, ctx);
	BN_mod(rsa->dmq1, rsa->d, r2, ctx);
	BN_mod_inverse(rsa->iqmp, rsa->q, rsa->p, ctx);

	BN_CTX_end(ctx);
	BN_CTX_free(ctx);
	return (RSA_check_key(rsa) == 1);
}
Beispiel #9
0
/* calculate p-1 and q-1 */
static void rsa_generate_additional_parameters(RSA *rsa)
{
	BIGNUM *aux = NULL;
	BN_CTX *ctx = NULL;

	if ((aux = BN_new()) == NULL)
		goto error;
	if ((ctx = BN_CTX_new()) == NULL)
		goto error;

	if ((BN_sub(aux, rsa->q, BN_value_one()) == 0) ||
	    (BN_mod(rsa->dmq1, rsa->d, aux, ctx) == 0) ||
	    (BN_sub(aux, rsa->p, BN_value_one()) == 0) ||
	    (BN_mod(rsa->dmp1, rsa->d, aux, ctx) == 0))
		goto error;

error:
	if (aux)
		BN_clear_free(aux);
	if (ctx)
		BN_CTX_free(ctx);
}
Beispiel #10
0
int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx)
{
    BIGNUM Ri,*R;

    BN_init(&Ri);
    R= &(mont->RR);					/* grab RR as a temp */
    BN_copy(&(mont->N),mod);			/* Set N */

    {
        BIGNUM tmod;
        BN_ULONG buf[2];

        mont->ri=(BN_num_bits(mod)+(BN_BITS2-1))/BN_BITS2*BN_BITS2;
        if (!(BN_zero(R))) goto err;
        if (!(BN_set_bit(R,BN_BITS2))) goto err;	/* R */

        buf[0]=mod->d[0]; /* tmod = N mod word size */
        buf[1]=0;
        tmod.d=buf;
        tmod.top=1;
        tmod.dmax=2;
        tmod.neg=mod->neg;
        /* Ri = R^-1 mod N*/
        if ((BN_mod_inverse(&Ri,R,&tmod,ctx)) == NULL)
            goto err;
        /* R*Ri */
        if (!(BN_lshift(&Ri,&Ri,BN_BITS2))) goto err;
        if (!BN_is_zero(&Ri))
        {
            if (!BN_sub_word(&Ri,1)) goto err;
        }
        else /* if N mod word size == 1 */
            /* Ri-- (mod word size) */
        {
            if (!BN_set_word(&Ri,BN_MASK2)) goto err;
        }
        /* Ni = (R*Ri-1)/N, keep only least significant word: */
        if (!(BN_div(&Ri,NULL,&Ri,&tmod,ctx))) goto err;
        mont->n0=Ri.d[0];
        BN_free(&Ri);
    }

    /* setup RR for conversions */
    if (!(BN_zero(&(mont->RR)))) goto err;
    if (!(BN_set_bit(&(mont->RR),mont->ri*2))) goto err;
    if (!(BN_mod(&(mont->RR),&(mont->RR),&(mont->N),ctx))) goto err;

    return(1);
err:
    return(0);
}
Beispiel #11
0
/* given the password(string), use SHA1 to hash it and return the result mod q */
static void hashpassword(BIGNUM *hash_result, const char *password, BN_CTX *ctx, const BIGNUM *q)
{
    SHA_CTX sha;
    size_t length = strlen(password);
    BIGNUM *hash_bn = BN_new();
    unsigned char digest[SHA_DIGEST_LENGTH];

    SHA1_Init(&sha);
    SHA1_Update(&sha, password, length);
    SHA1_Final(digest, &sha);
    BN_bin2bn(digest, SHA_DIGEST_LENGTH, hash_bn);

    BN_mod(hash_result, hash_bn, q, ctx);
}
bool android_pubkey_encode(const RSA* key, uint8_t* key_buffer, size_t size) {
  RSAPublicKey* key_struct = (RSAPublicKey*)key_buffer;
  bool ret = false;
  BN_CTX* ctx = BN_CTX_new();
  BIGNUM* r32 = BN_new();
  BIGNUM* n0inv = BN_new();
  BIGNUM* rr = BN_new();

  if (sizeof(RSAPublicKey) > size ||
      RSA_size(key) != ANDROID_PUBKEY_MODULUS_SIZE) {
    goto cleanup;
  }

  // Store the modulus size.
  key_struct->modulus_size_words = ANDROID_PUBKEY_MODULUS_SIZE_WORDS;

  // Compute and store n0inv = -1 / N[0] mod 2^32.
  if (!ctx || !r32 || !n0inv || !BN_set_bit(r32, 32) ||
      !BN_mod(n0inv, key->n, r32, ctx) ||
      !BN_mod_inverse(n0inv, n0inv, r32, ctx) || !BN_sub(n0inv, r32, n0inv)) {
    goto cleanup;
  }
  key_struct->n0inv = (uint32_t)BN_get_word(n0inv);

  // Store the modulus.
  if (!android_pubkey_encode_bignum(key->n, key_struct->modulus)) {
    goto cleanup;
  }

  // Compute and store rr = (2^(rsa_size)) ^ 2 mod N.
  if (!ctx || !rr || !BN_set_bit(rr, ANDROID_PUBKEY_MODULUS_SIZE * 8) ||
      !BN_mod_sqr(rr, rr, key->n, ctx) ||
      !android_pubkey_encode_bignum(rr, key_struct->rr)) {
    goto cleanup;
  }

  // Store the exponent.
  key_struct->exponent = (uint32_t)BN_get_word(key->e);

  ret = true;

cleanup:
  BN_free(rr);
  BN_free(n0inv);
  BN_free(r32);
  BN_CTX_free(ctx);
  return ret;
}
Beispiel #13
0
jstring Java_ch_ethz_inf_vs_talosmodule_cryptoalg_PaillierPrivNative_decryptpart(JNIEnv *env,
                                                                                jobject javaThis,
                                                                                jstring j_ciphertext,
                                                                                jstring j_p2,
                                                                                jstring j_a,
                                                                                jstring j_pinv,
                                                                                jstring j_two_p,
                                                                                jstring j_p,
                                                                                jstring j_hp) {
	BIGNUM *ciphertext, *p2, *a, *pinv, *two_p, *p, *hp;
	jstring* res;
	BIGNUM *temp = BN_new();
	BIGNUM *temp_2 = BN_new();
	BN_CTX *ctx = BN_CTX_new();

	ciphertext = convert_to_bignum(env, j_ciphertext);
	p2 = convert_to_bignum(env, j_p2);
	a = convert_to_bignum(env, j_a);
	pinv = convert_to_bignum(env, j_pinv);
	two_p = convert_to_bignum(env, j_two_p);
	p = convert_to_bignum(env, j_p);
	hp = convert_to_bignum(env, j_hp);

	// temp = ciphertext % p2
	BN_mod(temp, ciphertext, p2, ctx);
	// temp = g^(plaintext + n*r) % n2
	BN_mod_exp(temp, temp, a, p2, ctx);

	Lfast(temp_2, temp, pinv, two_p, p);

	//temp = g^(plaintext + n*r) % n2
	BN_mod_mul(temp, temp_2, hp, p, ctx);

	res = BN_to_jstring(env, temp);

	BN_CTX_free(ctx);
	BN_free(ciphertext);
    BN_free(p2);
    BN_free(a);
    BN_free(pinv);
    BN_free(two_p);
    BN_free(p);
    BN_free(hp);
   	BN_free(temp);
   	BN_free(temp_2);

	return res;
}
int paillier_encrypt(BIGNUM *c, const BIGNUM *m, const pubKey *key, BN_CTX *ctx)
{
    int ret = 1;
    BN_CTX_start(ctx);

    BIGNUM *r = BN_CTX_get(ctx);
    BIGNUM *tmp1 = BN_CTX_get(ctx);
    BIGNUM *tmp2 = BN_CTX_get(ctx);

    // 1. Let m be the message to be encrypted where m E Zn
    if (BN_cmp(m, key->n) >= 0)
    {
        fprintf(stderr, "Message not in Zn");
        goto end;
    }

    // 2. Select random r where r E Zn*
    do
    {
        if (!BN_rand(r, DEFAULT_KEY_LEN, 0, 0))
            goto end;
    }
    while (BN_is_zero(r));

    if (!BN_mod(r, r, key->n, ctx))
        goto end;

    // 3. Compute ciperthext as c = g^m*r^n mod n^2
    if (!BN_mod_exp(tmp1, key->g, m, key->n2, ctx))
        goto end;
    if (!BN_mod_exp(tmp2, r, key->n, key->n2, ctx))
        goto end;

    if (!BN_mod_mul(c, tmp1, tmp2, key->n2, ctx))
        goto end;

    ret = 0;
end:
    if (ret)
    {
        ERR_load_crypto_strings();
        fprintf(stderr, "Error ecnrypting: %s", ERR_error_string(ERR_get_error(), NULL));
    }

    BN_CTX_end(ctx);

    return ret;
}
Beispiel #15
0
//old
BIGNUM *Egcd(const BIGNUM *n, const BIGNUM *m, BIGNUM *x, BIGNUM *y)
	{
		//print_bn("n", n);
		//print_bn("m", m);
		
	BIGNUM *value = BN_new();
	BIGNUM *temp = BN_new();
	BIGNUM *t1 = BN_new();
	BIGNUM *t2 = BN_new();
	BIGNUM *new_m = BN_new();
	BN_CTX *ctx = BN_CTX_new();
	
	if (BN_is_zero(m))
		{
		BN_set_word(x, 1);
		BN_set_word(y, 0);
		value = BN_dup(n);
		
		//print_bn("x", x);
		//print_bn("y", y);
	
		return value;
		}	
		
	BN_mod(new_m, n, m, ctx);
	//printf("called once\n");
	value = BN_dup(Egcd(m, new_m, x, y));
	
	print_bn("n", n);
	print_bn("m", m);
	print_bn("old_x", x);
	print_bn("old_y", y);
	
	temp = BN_dup(x);
	
	x = BN_dup(y);
	
	/* y = temp - (n/m) * y */
	BN_div(t1, NULL, n, m, ctx);
	BN_mul(t2, t1, y, ctx);
	BN_sub(y, temp, t2);
	
	print_bn("x", x);
	print_bn("y", y);
	
	return value;
	}
Beispiel #16
0
BIGNUM *
auth_rsa_generate_challenge(Key *key)
{
	BIGNUM *challenge;
	BN_CTX *ctx;

	if ((challenge = BN_new()) == NULL)
		fatal("auth_rsa_generate_challenge: BN_new() failed");
	/* Generate a random challenge. */
	BN_rand(challenge, 256, 0, 0);
	if ((ctx = BN_CTX_new()) == NULL)
		fatal("auth_rsa_generate_challenge: BN_CTX_new() failed");
	BN_mod(challenge, challenge, key->rsa->n, ctx);
	BN_CTX_free(ctx);

	return challenge;
}
Beispiel #17
0
static int
probable_prime_dh(BIGNUM *rnd, int bits, const BIGNUM *add, const BIGNUM *rem,
    BN_CTX *ctx)
{
	int i, ret = 0;
	BIGNUM *t1;

	BN_CTX_start(ctx);
	if ((t1 = BN_CTX_get(ctx)) == NULL)
		goto err;

	if (!BN_rand(rnd, bits, 0, 1))
		goto err;

	/* we need ((rnd-rem) % add) == 0 */

	if (!BN_mod(t1, rnd, add, ctx))
		goto err;
	if (!BN_sub(rnd, rnd, t1))
		goto err;
	if (rem == NULL) {
		if (!BN_add_word(rnd, 1))
			goto err;
	} else {
		if (!BN_add(rnd, rnd, rem))
			goto err;
	}

	/* we now have a random number 'rand' to test. */

loop:
	for (i = 1; i < NUMPRIMES; i++) {
		/* check that rnd is a prime */
		if (BN_mod_word(rnd, (BN_ULONG)primes[i]) <= 1) {
			if (!BN_add(rnd, rnd, add))
				goto err;
			goto loop;
		}
	}
	ret = 1;

err:
	BN_CTX_end(ctx);
	bn_check_top(rnd);
	return (ret);
}
qint32 CryptoUtils::checkDHParams (BIGNUM *p, qint32 g) {
    if (g < 2 || g > 7) { return -1; }
    BIGNUM t;
    BN_init (&t);

    BIGNUM dh_g;
    BN_init (&dh_g);
    Utils::ensure (BN_set_word (&dh_g, 4 * g));

    Utils::ensure (BN_mod (&t, p, &dh_g, BN_ctx));
    qint32 x = BN_get_word (&t);
    Q_ASSERT(x >= 0 && x < 4 * g);

    BN_free (&dh_g);

    switch (g) {
    case 2:
        if (x != 7) { return -1; }
        break;
    case 3:
        if (x % 3 != 2 ) { return -1; }
        break;
    case 4:
        break;
    case 5:
        if (x % 5 != 1 && x % 5 != 4) { return -1; }
        break;
    case 6:
        if (x != 19 && x != 23) { return -1; }
        break;
    case 7:
        if (x % 7 != 3 && x % 7 != 5 && x % 7 != 6) { return -1; }
        break;
    }

    if (!checkPrime (p)) { return -1; }

    BIGNUM b;
    BN_init (&b);
    Utils::ensure (BN_set_word (&b, 2));
    Utils::ensure (BN_div (&t, 0, p, &b, BN_ctx));
    if (!checkPrime (&t)) { return -1; }
    BN_free (&b);
    BN_free (&t);
    return 0;
}
Beispiel #19
0
int test_mod(BIO *bp, BN_CTX *ctx)
	{
	BIGNUM *a,*b,*c,*d,*e;
	int i;

	a=BN_new();
	b=BN_new();
	c=BN_new();
	d=BN_new();
	e=BN_new();

	BN_bntest_rand(a,1024,0,0); /**/
	for (i=0; i<num0; i++)
		{
		BN_bntest_rand(b,450+i*10,0,0); /**/
		a->neg=rand_neg();
		b->neg=rand_neg();
		BN_mod(c,a,b,ctx);/**/
		if (bp != NULL)
			{
			if (!results)
				{
				BN_print(bp,a);
				BIO_puts(bp," % ");
				BN_print(bp,b);
				BIO_puts(bp," - ");
				}
			BN_print(bp,c);
			BIO_puts(bp,"\n");
			}
		BN_div(d,e,a,b,ctx);
		BN_sub(e,e,c);
		if(!BN_is_zero(e))
		    {
		    fprintf(stderr,"Modulo test failed!\n");
		    return 0;
		    }
		}
	BN_free(a);
	BN_free(b);
	BN_free(c);
	BN_free(d);
	BN_free(e);
	return(1);
	}
Beispiel #20
0
/* Output: username, bytes_A, len_A, Astr */
const char * srp_user_start_authentication(SRPUser *usr) {
    BN_CTX *ctx = BN_CTX_new();
    BN_mod_exp(usr->A, usr->ng->g, usr->a, usr->ng->N, ctx);
    BIGNUM *modCheck = BN_new();
    BN_mod(modCheck, usr->A, usr->ng->N, ctx);
    BN_free(modCheck);
    BN_CTX_free(ctx);
    
    int len_A = BN_num_bytes(usr->A);
    unsigned char *bytes_A = malloc(len_A);
    
    BN_bn2bin(usr->A, bytes_A);
    usr->bytes_A = bytes_A;
    usr->Astr = convert_to_lower(BN_bn2hex(usr->A));
    
    free(bytes_A);
    
    return usr->Astr;
}
EC_POINT *embed(const polypseud_ctx *ctx, const unsigned char *data, const size_t len) {
   BIGNUM *t1 = BN_bin2bn(data, len, NULL);
   BIGNUM *x = BN_new();
   BN_mod(x, t1, ctx->p, ctx->bn_ctx);

   EC_POINT *point = EC_POINT_new(ctx->ec_group);
   unsigned char counter = 0;
   int success = 0;
   while(!success) {
       success = EC_POINT_set_compressed_coordinates_GFp(ctx->ec_group, point, x, 1, ctx->bn_ctx);
       if(!success) {
           if(counter == 0) {
               BN_lshift(x, x, 8);
           }
           BN_add(x, x, BN_value_one());
       }
   }
   BN_free(x);
   BN_free(t1);
   return point;
}
Beispiel #22
0
    private_key private_key::generate_from_seed( const fc::sha256& seed, const fc::sha256& offset )
    {
        ssl_bignum z;
        BN_bin2bn((unsigned char*)&offset, sizeof(offset), z);

        ec_group group(EC_GROUP_new_by_curve_name(NID_secp256k1));
        bn_ctx ctx(BN_CTX_new());
        ssl_bignum order;
        EC_GROUP_get_order(group, order, ctx);

        // secexp = (seed + z) % order
        ssl_bignum secexp;
        BN_bin2bn((unsigned char*)&seed, sizeof(seed), secexp);
        BN_add(secexp, secexp, z);
        BN_mod(secexp, secexp, order, ctx);

        fc::sha256 secret;
        assert(BN_num_bytes(secexp) <= int64_t(sizeof(secret)));
        auto shift = sizeof(secret) - BN_num_bytes(secexp);
        BN_bn2bin(secexp, ((unsigned char*)&secret)+shift);
        return regenerate( secret );
    }
Beispiel #23
0
int compute_scalar_element(REQUEST *request, pwd_session_t *session, BN_CTX *bn_ctx)
{
	BIGNUM *mask = NULL;
	int ret = -1;

	MEM(session->private_value = BN_new());
	MEM(session->my_element = EC_POINT_new(session->group));
	MEM(session->my_scalar = BN_new());

	MEM(mask = BN_new());

	if (BN_rand_range(session->private_value, session->order) != 1) {
		REDEBUG("Unable to get randomness for private_value");
		goto error;
	}
	if (BN_rand_range(mask, session->order) != 1) {
		REDEBUG("Unable to get randomness for mask");
		goto error;
	}
	BN_add(session->my_scalar, session->private_value, mask);
	BN_mod(session->my_scalar, session->my_scalar, session->order, bn_ctx);

	if (!EC_POINT_mul(session->group, session->my_element, NULL, session->pwe, mask, bn_ctx)) {
		REDEBUG("Server element allocation failed");
		goto error;
	}

	if (!EC_POINT_invert(session->group, session->my_element, bn_ctx)) {
		REDEBUG("Server element inversion failed");
		goto error;
	}

	ret = 0;

error:
	BN_clear_free(mask);

	return ret;
}
static int dss_paramcheck(int nmod, BIGNUM *p, BIGNUM *q, BIGNUM *g,
                          BN_CTX *ctx)
{
    BIGNUM *rem = NULL;
    if (BN_num_bits(p) != nmod)
        return 0;
    if (BN_num_bits(q) != 160)
        return 0;
    if (BN_is_prime_ex(p, BN_prime_checks, ctx, NULL) != 1)
        return 0;
    if (BN_is_prime_ex(q, BN_prime_checks, ctx, NULL) != 1)
        return 0;
    rem = BN_new();
    if (!BN_mod(rem, p, q, ctx) || !BN_is_one(rem)
            || (BN_cmp(g, BN_value_one()) <= 0)
            || !BN_mod_exp(rem, g, q, p, ctx) || !BN_is_one(rem)) {
        BN_free(rem);
        return 0;
    }
    /* Todo: check g */
    BN_free(rem);
    return 1;
}
Beispiel #25
0
static void
bmod(void)
{
	struct number	*a, *b;
	struct number	*r;
	u_int		scale;
	BN_CTX		*ctx;

	a = pop_number();
	if (a == NULL) {
		return;
	}
	b = pop_number();
	if (b == NULL) {
		push_number(a);
		return;
	}

	r = new_number();
	scale = max(a->scale, b->scale);
	r->scale = max(b->scale, a->scale + bmachine.scale);

	if (BN_is_zero(a->number))
		warnx("remainder by zero");
	else {
		normalize(a, scale);
		normalize(b, scale + bmachine.scale);

		ctx = BN_CTX_new();
		bn_checkp(ctx);
		bn_check(BN_mod(r->number, b->number, a->number, ctx));
		BN_CTX_free(ctx);
	}
	push_number(r);
	free_number(a);
	free_number(b);
}
Beispiel #26
0
int
compute_scalar_element (pwd_session_t *sess, BN_CTX *bnctx)
{
    BIGNUM *mask = NULL;
    int ret = -1;

    if (((sess->private_value = BN_new()) == NULL) ||
	((sess->my_element = EC_POINT_new(sess->group)) == NULL) ||
	((sess->my_scalar = BN_new()) == NULL) ||
	((mask = BN_new()) == NULL)) {
	DEBUG2("server scalar allocation failed");
	goto fail;
    }

    BN_rand_range(sess->private_value, sess->order);
    BN_rand_range(mask, sess->order);
    BN_add(sess->my_scalar, sess->private_value, mask);
    BN_mod(sess->my_scalar, sess->my_scalar, sess->order,
	   bnctx);

    if (!EC_POINT_mul(sess->group, sess->my_element, NULL,
		      sess->pwe, mask, bnctx)) {
	DEBUG2("server element allocation failed");
	goto fail;
    }

    if (!EC_POINT_invert(sess->group, sess->my_element, bnctx)) {
	DEBUG2("server element inversion failed");
	goto fail;
    }

    ret = 0;
fail:
    BN_free(mask);

    return ret;
}
static int get_key_bignum(BIGNUM *num, int num_bits, uint32_t *key_mod)
{
	BIGNUM *tmp, *big2, *big32, *big2_32;
	BN_CTX *ctx;
	int ret;

	tmp = BN_new();
	big2 = BN_new();
	big32 = BN_new();
	big2_32 = BN_new();
	if (!tmp || !big2 || !big32 || !big2_32) {
		fprintf(stderr, "Out of memory (bignum)\n");
		return -1;
	}
	ctx = BN_CTX_new();
	if (!tmp) {
		fprintf(stderr, "Out of memory (bignum context)\n");
		return -1;
	}
	BN_set_word(big2, 2L);
	BN_set_word(big32, 32L);
	BN_exp(big2_32, big2, big32, ctx); /* B = 2^32 */

	for (ret = 0; ret <= 63; ret++) {
		BN_mod(tmp, num, big2_32, ctx); /* n = N mod B */
		key_mod[ret] = htonl(BN_get_word(tmp));
		BN_rshift(num, num, 32); /*  N = N/B */
	}

	BN_free(tmp);
	BN_free(big2);
	BN_free(big32);
	BN_free(big2_32);

	return 0;
}
Beispiel #28
0
int CREDLIB_mod_hash( BIGNUM* r, BIGNUM* n, BIGNUM* n2,
                      byte* out, int out_len, BIGNUM* m, BN_CTX* ctx ) {
    EXCEPTION;
    SHA_CTX sha1;
    byte hash[ SHA_DIGEST_LENGTH ];
    byte* dat = NULL;
    int dat_len_s, req_len, alt_len;
    int* dat_len=&dat_len_s;
 
    if ( !m || !r || !ctx ) { THROW( CREDLIB_NULL_PTR ); }
    if ( !n && !n2 && !out ) { THROW( CREDLIB_NULL_PTR ); } /* no input! */
 
    SHA1_Init( &sha1 );
 
    req_len = ( n ? CREDLIB_calc_bn( n ) : 0 )
        + ( n2 ? CREDLIB_calc_bn( n2 ) : 0 );
 
    if ( req_len > 0 ) {
        TRY( CREDLIB_out( &dat, &dat_len, &alt_len, req_len ) );
        TRYIO_start( dat );
        /* use serialization system to n||n2 to prevent ambiguity */
        if ( n ) { TRYIO( CREDLIB_write_bn( ptr, n ) ); }
        if ( n2 ) { TRYIO( CREDLIB_write_bn( ptr, n2 ) ); }
 
        SHA1_Update( &sha1, dat, TRYIO_len( dat ) );
    }
    if ( out ) { SHA1_Update( &sha1, out, out_len ); }
    SHA1_Final( hash, &sha1 );
     
    CREDLIB_free( dat );
    TRYM( BN_bin2bn( hash, SHA_DIGEST_LENGTH, r ) );
    TRYM( BN_mod( r, r, m, ctx ) );
     
 cleanup:
    return ret;
}
int
dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits, const EVP_MD *evpmd,
    const unsigned char *seed_in, size_t seed_len, unsigned char *seed_out,
    int *counter_ret, unsigned long *h_ret, BN_GENCB *cb)
{
	int ok = 0;
	unsigned char seed[SHA256_DIGEST_LENGTH];
	unsigned char md[SHA256_DIGEST_LENGTH];
	unsigned char buf[SHA256_DIGEST_LENGTH], buf2[SHA256_DIGEST_LENGTH];
	BIGNUM *r0, *W, *X, *c, *test;
	BIGNUM *g = NULL, *q = NULL, *p = NULL;
	BN_MONT_CTX *mont = NULL;
	int i, k, n = 0, m = 0, qsize = qbits >> 3;
	int counter = 0;
	int r = 0;
	BN_CTX *ctx = NULL;
	unsigned int h = 2;

	if (qsize != SHA_DIGEST_LENGTH && qsize != SHA224_DIGEST_LENGTH &&
	    qsize != SHA256_DIGEST_LENGTH)
		/* invalid q size */
		return 0;

	if (evpmd == NULL)
		/* use SHA1 as default */
		evpmd = EVP_sha1();

	if (bits < 512)
		bits = 512;

	bits = (bits + 63) / 64 * 64;

	/*
	 * NB: seed_len == 0 is special case: copy generated seed to
 	 * seed_in if it is not NULL.
 	 */
	if (seed_len && seed_len < (size_t)qsize)
		seed_in = NULL;		/* seed buffer too small -- ignore */
	/*
	 * App. 2.2 of FIPS PUB 186 allows larger SEED,
	 * but our internal buffers are restricted to 160 bits
	 */
	if (seed_len > (size_t)qsize) 
		seed_len = qsize;
	if (seed_in != NULL)
		memcpy(seed, seed_in, seed_len);

	if ((ctx=BN_CTX_new()) == NULL)
		goto err;

	if ((mont=BN_MONT_CTX_new()) == NULL)
		goto err;

	BN_CTX_start(ctx);
	r0 = BN_CTX_get(ctx);
	g = BN_CTX_get(ctx);
	W = BN_CTX_get(ctx);
	q = BN_CTX_get(ctx);
	X = BN_CTX_get(ctx);
	c = BN_CTX_get(ctx);
	p = BN_CTX_get(ctx);
	test = BN_CTX_get(ctx);

	if (!BN_lshift(test, BN_value_one(), bits - 1))
		goto err;

	for (;;) {
		for (;;) { /* find q */
			int seed_is_random;

			/* step 1 */
			if (!BN_GENCB_call(cb, 0, m++))
				goto err;

			if (!seed_len) {
				RAND_pseudo_bytes(seed, qsize);
				seed_is_random = 1;
			} else {
				seed_is_random = 0;
				/* use random seed if 'seed_in' turns out
				   to be bad */
				seed_len = 0;
			}
			memcpy(buf, seed, qsize);
			memcpy(buf2, seed, qsize);
			/* precompute "SEED + 1" for step 7: */
			for (i = qsize - 1; i >= 0; i--) {
				buf[i]++;
				if (buf[i] != 0)
					break;
			}

			/* step 2 */
			if (!EVP_Digest(seed, qsize, md,   NULL, evpmd, NULL))
				goto err;
			if (!EVP_Digest(buf,  qsize, buf2, NULL, evpmd, NULL))
				goto err;
			for (i = 0; i < qsize; i++)
				md[i] ^= buf2[i];

			/* step 3 */
			md[0] |= 0x80;
			md[qsize - 1] |= 0x01;
			if (!BN_bin2bn(md, qsize, q))
				goto err;

			/* step 4 */
			r = BN_is_prime_fasttest_ex(q, DSS_prime_checks, ctx,
			    seed_is_random, cb);
			if (r > 0)
				break;
			if (r != 0)
				goto err;

			/* do a callback call */
			/* step 5 */
		}

		if (!BN_GENCB_call(cb, 2, 0))
			goto err;
		if (!BN_GENCB_call(cb, 3, 0))
			goto err;

		/* step 6 */
		counter = 0;
		/* "offset = 2" */

		n = (bits - 1) / 160;

		for (;;) {
			if (counter != 0 && !BN_GENCB_call(cb, 0, counter))
				goto err;

			/* step 7 */
			BN_zero(W);
			/* now 'buf' contains "SEED + offset - 1" */
			for (k = 0; k <= n; k++) {
				/* obtain "SEED + offset + k" by incrementing: */
				for (i = qsize - 1; i >= 0; i--) {
					buf[i]++;
					if (buf[i] != 0)
						break;
				}

				if (!EVP_Digest(buf, qsize, md ,NULL, evpmd,
				    NULL))
					goto err;

				/* step 8 */
				if (!BN_bin2bn(md, qsize, r0))
					goto err;
				if (!BN_lshift(r0, r0, (qsize << 3) * k))
					goto err;
				if (!BN_add(W, W, r0))
					goto err;
			}

			/* more of step 8 */
			if (!BN_mask_bits(W, bits - 1))
				goto err;
			if (!BN_copy(X, W))
				goto err;
			if (!BN_add(X, X, test))
				goto err;

			/* step 9 */
			if (!BN_lshift1(r0, q))
				goto err;
			if (!BN_mod(c, X, r0, ctx))
				goto err;
			if (!BN_sub(r0, c, BN_value_one()))
				goto err;
			if (!BN_sub(p, X, r0))
				goto err;

			/* step 10 */
			if (BN_cmp(p, test) >= 0) {
				/* step 11 */
				r = BN_is_prime_fasttest_ex(p, DSS_prime_checks,
				    ctx, 1, cb);
				if (r > 0)
					goto end; /* found it */
				if (r != 0)
					goto err;
			}

			/* step 13 */
			counter++;
			/* "offset = offset + n + 1" */

			/* step 14 */
			if (counter >= 4096)
				break;
		}
	}
end:
	if (!BN_GENCB_call(cb, 2, 1))
		goto err;

	/* We now need to generate g */
	/* Set r0=(p-1)/q */
	if (!BN_sub(test, p, BN_value_one()))
		goto err;
	if (!BN_div(r0, NULL, test, q, ctx))
		goto err;

	if (!BN_set_word(test, h))
		goto err;
	if (!BN_MONT_CTX_set(mont, p, ctx))
		goto err;

	for (;;) {
		/* g=test^r0%p */
		if (!BN_mod_exp_mont(g, test, r0, p, ctx, mont))
			goto err;
		if (!BN_is_one(g))
			break;
		if (!BN_add(test, test, BN_value_one()))
			goto err;
		h++;
	}

	if (!BN_GENCB_call(cb, 3, 1))
		goto err;

	ok = 1;
err:
	if (ok) {
		if (ret->p)
			BN_free(ret->p);
		if (ret->q)
			BN_free(ret->q);
		if (ret->g)
			BN_free(ret->g);
		ret->p = BN_dup(p);
		ret->q = BN_dup(q);
		ret->g = BN_dup(g);
		if (ret->p == NULL || ret->q == NULL || ret->g == NULL) {
			ok = 0;
			goto err;
		}
		if (counter_ret != NULL)
			*counter_ret = counter;
		if (h_ret != NULL)
			*h_ret = h;
		if (seed_out)
			memcpy(seed_out, seed, qsize);
	}
	if (ctx) {
		BN_CTX_end(ctx);
		BN_CTX_free(ctx);
	}
	if (mont != NULL)
		BN_MONT_CTX_free(mont);
	return ok;
}
Beispiel #30
0
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);
	}