Exemple #1
0
int vb_keyb_from_rsa(struct rsa_st *rsa_private_key,
		     uint8_t **keyb_data, uint32_t *keyb_size)
{
	uint32_t i, nwords;
	BIGNUM *N = NULL;
	BIGNUM *Big1 = NULL, *Big2 = NULL, *Big32 = NULL, *BigMinus1 = NULL;
	BIGNUM *B = NULL;
	BIGNUM *N0inv = NULL, *R = NULL, *RR = NULL;
	BIGNUM *RRTemp = NULL, *NnumBits = NULL;
	BIGNUM *n = NULL, *rr = NULL;
	const BIGNUM *rsa_private_key_n;
	BN_CTX *bn_ctx = BN_CTX_new();
	uint32_t n0invout;
	uint32_t bufsize;
	uint32_t *outbuf;
	int retval = 1;

	/* Size of RSA key in 32-bit words */
	nwords = RSA_size(rsa_private_key) / 4;

	bufsize = (2 + nwords + nwords) * sizeof(uint32_t);
	outbuf = malloc(bufsize);
	if (!outbuf)
		goto done;

	*keyb_data = (uint8_t *)outbuf;
	*keyb_size = bufsize;

	*outbuf++ = nwords;

	/* Initialize BIGNUMs */
#define NEW_BIGNUM(x) do { x = BN_new(); if (!x) goto done; } while (0)
	NEW_BIGNUM(N);
	NEW_BIGNUM(Big1);
	NEW_BIGNUM(Big2);
	NEW_BIGNUM(Big32);
	NEW_BIGNUM(BigMinus1);
	NEW_BIGNUM(N0inv);
	NEW_BIGNUM(R);
	NEW_BIGNUM(RR);
	NEW_BIGNUM(RRTemp);
	NEW_BIGNUM(NnumBits);
	NEW_BIGNUM(n);
	NEW_BIGNUM(rr);
	NEW_BIGNUM(B);
#undef NEW_BIGNUM

	RSA_get0_key(rsa_private_key, &rsa_private_key_n, NULL, NULL);
	BN_copy(N, rsa_private_key_n);
	BN_set_word(Big1, 1L);
	BN_set_word(Big2, 2L);
	BN_set_word(Big32, 32L);
	BN_sub(BigMinus1, Big1, Big2);

	BN_exp(B, Big2, Big32, bn_ctx); /* B = 2^32 */

	/* Calculate and output N0inv = -1 / N[0] mod 2^32 */
	BN_mod_inverse(N0inv, N, B, bn_ctx);
	BN_sub(N0inv, B, N0inv);
	n0invout = BN_get_word(N0inv);

	*outbuf++ = n0invout;

	/* Calculate R = 2^(# of key bits) */
	BN_set_word(NnumBits, BN_num_bits(N));
	BN_exp(R, Big2, NnumBits, bn_ctx);

	/* Calculate RR = R^2 mod N */
	BN_copy(RR, R);
	BN_mul(RRTemp, RR, R, bn_ctx);
	BN_mod(RR, RRTemp, N, bn_ctx);


	/* Write out modulus as little endian array of integers. */
	for (i = 0; i < nwords; ++i) {
		uint32_t nout;

		BN_mod(n, N, B, bn_ctx); /* n = N mod B */
		nout = BN_get_word(n);
		*outbuf++ = nout;

		BN_rshift(N, N, 32); /*  N = N/B */
	}

	/* Write R^2 as little endian array of integers. */
	for (i = 0; i < nwords; ++i) {
		uint32_t rrout;

		BN_mod(rr, RR, B, bn_ctx); /* rr = RR mod B */
		rrout = BN_get_word(rr);
		*outbuf++ = rrout;

		BN_rshift(RR, RR, 32); /* RR = RR/B */
	}

	outbuf = NULL;
	retval = 0;

done:
	free(outbuf);
	/* Free BIGNUMs. */
	BN_free(Big1);
	BN_free(Big2);
	BN_free(Big32);
	BN_free(BigMinus1);
	BN_free(N0inv);
	BN_free(R);
	BN_free(RRTemp);
	BN_free(NnumBits);
	BN_free(n);
	BN_free(rr);

	return retval;
}
Exemple #2
0
int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx) {
  int ret = 0;
  BIGNUM *Ri, *R;
  BIGNUM tmod;
  BN_ULONG buf[2];

  if (BN_is_zero(mod)) {
    OPENSSL_PUT_ERROR(BN, BN_R_DIV_BY_ZERO);
    return 0;
  }

  BN_CTX_start(ctx);
  Ri = BN_CTX_get(ctx);
  if (Ri == NULL) {
    goto err;
  }
  R = &mont->RR; /* grab RR as a temp */
  if (!BN_copy(&mont->N, mod)) {
    goto err; /* Set N */
  }
  mont->N.neg = 0;

  BN_init(&tmod);
  tmod.d = buf;
  tmod.dmax = 2;
  tmod.neg = 0;

  mont->ri = (BN_num_bits(mod) + (BN_BITS2 - 1)) / BN_BITS2 * BN_BITS2;

#if defined(OPENSSL_BN_ASM_MONT) && (BN_BITS2 <= 32)
  /* Only certain BN_BITS2<=32 platforms actually make use of
   * n0[1], and we could use the #else case (with a shorter R
   * value) for the others.  However, currently only the assembler
   * files do know which is which. */

  BN_zero(R);
  if (!BN_set_bit(R, 2 * BN_BITS2)) {
    goto err;
  }

  tmod.top = 0;
  if ((buf[0] = mod->d[0])) {
    tmod.top = 1;
  }
  if ((buf[1] = mod->top > 1 ? mod->d[1] : 0)) {
    tmod.top = 2;
  }

  if (BN_mod_inverse(Ri, R, &tmod, ctx) == NULL) {
    goto err;
  }
  if (!BN_lshift(Ri, Ri, 2 * BN_BITS2)) {
    goto err; /* R*Ri */
  }
  if (!BN_is_zero(Ri)) {
    if (!BN_sub_word(Ri, 1)) {
      goto err;
    }
  } else {
    /* if N mod word size == 1 */
    if (bn_expand(Ri, (int)sizeof(BN_ULONG) * 2) == NULL) {
      goto err;
    }
    /* Ri-- (mod double word size) */
    Ri->neg = 0;
    Ri->d[0] = BN_MASK2;
    Ri->d[1] = BN_MASK2;
    Ri->top = 2;
  }

  if (!BN_div(Ri, NULL, Ri, &tmod, ctx)) {
    goto err;
  }
  /* Ni = (R*Ri-1)/N,
   * keep only couple of least significant words: */
  mont->n0[0] = (Ri->top > 0) ? Ri->d[0] : 0;
  mont->n0[1] = (Ri->top > 1) ? Ri->d[1] : 0;
#else
  BN_zero(R);
  if (!BN_set_bit(R, BN_BITS2)) {
    goto err; /* R */
  }

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

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

  ret = 1;

err:
  BN_CTX_end(ctx);
  return ret;
}
Exemple #3
0
static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb)
	{
	BIGNUM *r0=NULL,*r1=NULL,*r2=NULL,*r3=NULL,*tmp;
	BIGNUM local_r0,local_d,local_p;
	BIGNUM *pr0,*d,*p;
	int bitsp,bitsq,ok= -1,n=0;
	BN_CTX *ctx=NULL;

#ifdef OPENSSL_FIPS
	if(FIPS_selftest_failed())
	    {
	    FIPSerr(FIPS_F_RSA_BUILTIN_KEYGEN,FIPS_R_FIPS_SELFTEST_FAILED);
	    return 0;
	    }

	if (FIPS_module_mode() && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW) 
		&& (bits < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS))
	    {
	    FIPSerr(FIPS_F_RSA_BUILTIN_KEYGEN,FIPS_R_KEY_TOO_SHORT);
	    return 0;
	    }
	if (!fips_check_rsa_prng(rsa, bits))
	    return 0;
#endif

	ctx=BN_CTX_new();
	if (ctx == NULL) goto err;
	BN_CTX_start(ctx);
	r0 = BN_CTX_get(ctx);
	r1 = BN_CTX_get(ctx);
	r2 = BN_CTX_get(ctx);
	r3 = BN_CTX_get(ctx);
	if (r3 == NULL) goto err;

	bitsp=(bits+1)/2;
	bitsq=bits-bitsp;

	/* We need the RSA components non-NULL */
	if(!rsa->n && ((rsa->n=BN_new()) == NULL)) goto err;
	if(!rsa->d && ((rsa->d=BN_new()) == NULL)) goto err;
	if(!rsa->e && ((rsa->e=BN_new()) == NULL)) goto err;
	if(!rsa->p && ((rsa->p=BN_new()) == NULL)) goto err;
	if(!rsa->q && ((rsa->q=BN_new()) == NULL)) goto err;
	if(!rsa->dmp1 && ((rsa->dmp1=BN_new()) == NULL)) goto err;
	if(!rsa->dmq1 && ((rsa->dmq1=BN_new()) == NULL)) goto err;
	if(!rsa->iqmp && ((rsa->iqmp=BN_new()) == NULL)) goto err;

	BN_copy(rsa->e, e_value);

	/* generate p and q */
	for (;;)
		{
		if(!BN_generate_prime_ex(rsa->p, bitsp, 0, NULL, NULL, cb))
			goto err;
		if (!BN_sub(r2,rsa->p,BN_value_one())) goto err;
		if (!BN_gcd(r1,r2,rsa->e,ctx)) goto err;
		if (BN_is_one(r1)) break;
		if(!BN_GENCB_call(cb, 2, n++))
			goto err;
		}
	if(!BN_GENCB_call(cb, 3, 0))
		goto err;
	for (;;)
		{
		/* When generating ridiculously small keys, we can get stuck
		 * continually regenerating the same prime values. Check for
		 * this and bail if it happens 3 times. */
		unsigned int degenerate = 0;
		do
			{
			if(!BN_generate_prime_ex(rsa->q, bitsq, 0, NULL, NULL, cb))
				goto err;
			} while((BN_cmp(rsa->p, rsa->q) == 0) && (++degenerate < 3));
		if(degenerate == 3)
			{
			ok = 0; /* we set our own err */
			RSAerr(RSA_F_RSA_BUILTIN_KEYGEN,RSA_R_KEY_SIZE_TOO_SMALL);
			goto err;
			}
		if (!BN_sub(r2,rsa->q,BN_value_one())) goto err;
		if (!BN_gcd(r1,r2,rsa->e,ctx)) goto err;
		if (BN_is_one(r1))
			break;
		if(!BN_GENCB_call(cb, 2, n++))
			goto err;
		}
	if(!BN_GENCB_call(cb, 3, 1))
		goto err;
	if (BN_cmp(rsa->p,rsa->q) < 0)
		{
		tmp=rsa->p;
		rsa->p=rsa->q;
		rsa->q=tmp;
		}

	/* calculate n */
	if (!BN_mul(rsa->n,rsa->p,rsa->q,ctx)) goto err;

	/* calculate d */
	if (!BN_sub(r1,rsa->p,BN_value_one())) goto err;	/* p-1 */
	if (!BN_sub(r2,rsa->q,BN_value_one())) goto err;	/* q-1 */
	if (!BN_mul(r0,r1,r2,ctx)) goto err;	/* (p-1)(q-1) */
	if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
		{
		  pr0 = &local_r0;
		  BN_with_flags(pr0, r0, BN_FLG_CONSTTIME);
		}
	else
	  pr0 = r0;
	if (!BN_mod_inverse(rsa->d,rsa->e,pr0,ctx)) goto err;	/* d */

	/* set up d for correct BN_FLG_CONSTTIME flag */
	if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
		{
		d = &local_d;
		BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME);
		}
	else
		d = rsa->d;

	/* calculate d mod (p-1) */
	if (!BN_mod(rsa->dmp1,d,r1,ctx)) goto err;

	/* calculate d mod (q-1) */
	if (!BN_mod(rsa->dmq1,d,r2,ctx)) goto err;

	/* calculate inverse of q mod p */
	if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
		{
		p = &local_p;
		BN_with_flags(p, rsa->p, BN_FLG_CONSTTIME);
		}
	else
		p = rsa->p;
	if (!BN_mod_inverse(rsa->iqmp,rsa->q,p,ctx)) goto err;

#ifdef OPENSSL_FIPS
	if(!fips_check_rsa(rsa))
	    goto err;
#endif

	ok=1;
err:
	if (ok == -1)
		{
		RSAerr(RSA_F_RSA_BUILTIN_KEYGEN,ERR_LIB_BN);
		ok=0;
		}
	if (ctx != NULL)
		{
		BN_CTX_end(ctx);
		BN_CTX_free(ctx);
		}

	return ok;
	}
Exemple #4
0
int
pgp_elgamal_private_decrypt(uint8_t *out,
				const uint8_t *g_to_k,
				const uint8_t *in,
				size_t length,
				const pgp_elgamal_seckey_t *seckey,
				const pgp_elgamal_pubkey_t *pubkey)
{
	BIGNUM	*bndiv;
	BIGNUM	*c1x;
	BN_CTX	*tmp;
	BIGNUM	*c1;
	BIGNUM	*c2;
	BIGNUM	*p;
	BIGNUM	*x;
	BIGNUM	*m;
	int	 ret;

	ret = 0;
	/* c1 and c2 are in g_to_k and in, respectively*/
	c1 = BN_bin2bn(g_to_k, (int)length, NULL);
	c2 = BN_bin2bn(in, (int)length, NULL);
	/* other bits */
	p = pubkey->p;
	x = seckey->x;
	c1x = BN_new();
	bndiv = BN_new();
	m = BN_new();
	tmp = BN_CTX_new();
	if (!c1 || !c2 || !p || !x || !c1x || !bndiv || !m || !tmp) {
		goto done;
	}
	/*
	 * m = c2 / (c1^x)
	 */
	if (!BN_mod_exp(c1x, c1, x, p, tmp)) {
		goto done;
	}
	if (!BN_mod_inverse(bndiv, c1x, p, tmp)) {
		goto done;
	}
	if (!BN_mod_mul(m, c2, bndiv, p, tmp)) {
		goto done;
	}
	/* result */
	ret = BN_bn2bin(m, out);
done:
	if (tmp) {
		BN_CTX_free(tmp);
	}
	if (m) {
		BN_clear_free(m);
	}
	if (bndiv) {
		BN_clear_free(bndiv);
	}
	if (c1x) {
		BN_clear_free(c1x);
	}
	if (x) {
		BN_clear_free(x);
	}
	if (p) {
		BN_clear_free(p);
	}
	if (c1) {
		BN_clear_free(c1);
	}
	if (c2) {
		BN_clear_free(c2);
	}
	return ret;
}
Exemple #5
0
int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx)
{
    int ret = 0;
    BIGNUM *Ri,*R;

    BN_CTX_start(ctx);
    if((Ri = BN_CTX_get(ctx)) == NULL) goto err;
    R= &(mont->RR);					/* grab RR as a temp */
    if (!BN_copy(&(mont->N),mod)) goto err;		/* Set N */
    mont->N.neg = 0;

#ifdef MONT_WORD
    {
        BIGNUM tmod;
        BN_ULONG buf[2];

        mont->ri=(BN_num_bits(mod)+(BN_BITS2-1))/BN_BITS2*BN_BITS2;
        BN_zero(R);
        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 = buf[0] != 0 ? 1 : 0;
        tmod.dmax=2;
        tmod.neg=0;
        /* Ri = R^-1 mod N*/
        if ((BN_mod_inverse(Ri,R,&tmod,ctx)) == NULL)
            goto err;
        if (!BN_lshift(Ri,Ri,BN_BITS2)) goto err; /* R*Ri */
        if (!BN_is_zero(Ri))
        {
            if (!BN_sub_word(Ri,1)) goto err;
        }
        else /* if N mod word size == 1 */
        {
            if (!BN_set_word(Ri,BN_MASK2)) goto err;  /* Ri-- (mod word size) */
        }
        if (!BN_div(Ri,NULL,Ri,&tmod,ctx)) goto err;
        /* Ni = (R*Ri-1)/N,
         * keep only least significant word: */
        mont->n0 = (Ri->top > 0) ? Ri->d[0] : 0;
    }
#else /* !MONT_WORD */
    {   /* bignum version */
        mont->ri=BN_num_bits(&mont->N);
        BN_zero(R);
        if (!BN_set_bit(R,mont->ri)) goto err;  /* R = 2^ri */
        /* Ri = R^-1 mod N*/
        if ((BN_mod_inverse(Ri,R,&mont->N,ctx)) == NULL)
            goto err;
        if (!BN_lshift(Ri,Ri,mont->ri)) goto err; /* R*Ri */
        if (!BN_sub_word(Ri,1)) goto err;
        /* Ni = (R*Ri-1) / N */
        if (!BN_div(&(mont->Ni),NULL,Ri,&mont->N,ctx)) goto err;
    }
#endif

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

    ret = 1;
err:
    BN_CTX_end(ctx);
    return ret;
}
// unsigned char *rgbHashData, 哈希
// unsigned char *rgbKeyDb, 私钥
// unsigned char *rs             签名
void eccHashSign(unsigned char *rgbHashData, unsigned char *rgbKeyDb, unsigned char *rs)
{
	int ok = 0;
	const EC_GROUP *ec_group;
	BIGNUM *priv_key;
	const BIGNUM *ck;
	BIGNUM *k = NULL;
	BN_CTX *ctx = NULL;
	BIGNUM *order = NULL;
	BIGNUM *e = NULL;
	BIGNUM *bn = NULL;
	int i;
	BIGNUM *r= BN_new(), *s = BN_new();


	EC_KEY *ec_key = EC_KEY_new_by_curve_name(NID_sm2p256v1);
	ec_group = EC_KEY_get0_group(ec_key);
	priv_key = BN_new();
	BN_bin2bn(rgbKeyDb, 32, priv_key);
	EC_KEY_set_private_key(ec_key, priv_key);
	if (!ec_group || !priv_key) {
	}

	ctx = BN_CTX_new();
	order = BN_new();
	e = BN_new();
	bn = BN_new();
	if (!ctx || !order || !e || !bn) {
		ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
		goto err;
	}
	if (!EC_GROUP_get_order(ec_group, order, ctx)) {
		ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB);
		goto err;
	}

	/* convert dgst to e */
	i = BN_num_bits(order);
#if 0
	if (8 * dgst_len > i) {
		dgst_len = (i + 7)/8;
	}
#endif
	if (!BN_bin2bn(rgbHashData, 32, e)) {
		ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
		goto err;
	}

#if 0
	if ((8 * dgst_len > i) && !BN_rshift(e, e, 8 - (i & 0x7))) {
		ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
		goto err;
	}
#endif

	do {
		/* use or compute k and (kG).x */
			if (!sm2_sign_setup(ec_key, ctx, &k, &r)) {
				ECDSAerr(ECDSA_F_ECDSA_DO_SIGN,ERR_R_ECDSA_LIB);
				goto err;
			}
			ck = k;


		/* r = e + x (mod n) */	
		if (!BN_mod_add(r, r, e, order, ctx)) {
			ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
			goto err;
		}


		if (!BN_mod_add(bn, r, ck, order, ctx)) {
			ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
			goto err;
		}

		/* check r != 0 && r + k != n */
		if (BN_is_zero(r) || BN_is_zero(bn)) {
				continue;
		}

		/* s = ((1 + d)^-1 * (k - rd)) mod n */
		if (!BN_one(bn)) {
			ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
			goto err;
		}
		if (!BN_mod_add(s, priv_key, bn, order, ctx)) {
			ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
			goto err;
		}
		if (!BN_mod_inverse(s, s, order, ctx)) {
			ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
			goto err;
		}

		if (!BN_mod_mul(bn, r, priv_key, order, ctx)) {
			ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
			goto err;
		}
		if (!BN_mod_sub(bn, ck, bn, order, ctx)) {
			ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
			goto err;
		}
		if (!BN_mod_mul(s, s, bn, order, ctx)) {
			ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
			goto err;
		}

		/* check s != 0 */
		if (!BN_is_zero(s)) 
			break;

	} while (1);

	ok = 1;
	BN_bn2bin(r, rs);
	BN_bn2bin(s, rs + 32);

err:
	if (k) BN_free(k);	
	if (ctx) BN_CTX_free(ctx);
	if (order) BN_free(order);
	if (e) BN_free(e);
	if (bn) BN_free(bn);	

}
Exemple #7
0
/**
 \ingroup HighLevel_KeyGenerate
 \brief Generates an RSA keypair
 \param numbits Modulus size
 \param e Public Exponent
 \param keydata Pointer to keydata struct to hold new key
 \return 1 if key generated successfully; otherwise 0
 \note It is the caller's responsibility to call pgp_keydata_free(keydata)
*/
static unsigned 
rsa_generate_keypair(pgp_key_t *keydata,
			const int numbits,
			const unsigned long e,
			const char *hashalg,
			const char *cipher)
{
	pgp_seckey_t *seckey;
	RSA            *rsa;
	BN_CTX         *ctx;
	pgp_output_t *output;
	pgp_memory_t   *mem;

	ctx = BN_CTX_new();
	pgp_keydata_init(keydata, PGP_PTAG_CT_SECRET_KEY);
	seckey = pgp_get_writable_seckey(keydata);

	/* generate the key pair */

	rsa = RSA_generate_key(numbits, e, NULL, NULL);

	/* populate pgp key from ssl key */

	seckey->pubkey.version = PGP_V4;
	seckey->pubkey.birthtime = time(NULL);
	seckey->pubkey.days_valid = 0;
	seckey->pubkey.alg = PGP_PKA_RSA;

	seckey->pubkey.key.rsa.n = BN_dup(rsa->n);
	seckey->pubkey.key.rsa.e = BN_dup(rsa->e);

	seckey->s2k_usage = PGP_S2KU_ENCRYPTED_AND_HASHED;
	seckey->s2k_specifier = PGP_S2KS_SALTED;
	/* seckey->s2k_specifier=PGP_S2KS_SIMPLE; */
	if ((seckey->hash_alg = pgp_str_to_hash_alg(hashalg)) == PGP_HASH_UNKNOWN) {
		seckey->hash_alg = PGP_HASH_SHA1;
	}
	seckey->alg = pgp_str_to_cipher(cipher);
	seckey->octetc = 0;
	seckey->checksum = 0;

	seckey->key.rsa.d = BN_dup(rsa->d);
	seckey->key.rsa.p = BN_dup(rsa->p);
	seckey->key.rsa.q = BN_dup(rsa->q);
	seckey->key.rsa.u = BN_mod_inverse(NULL, rsa->p, rsa->q, ctx);
	if (seckey->key.rsa.u == NULL) {
		(void) fprintf(stderr, "seckey->key.rsa.u is NULL\n");
		return 0;
	}
	BN_CTX_free(ctx);

	RSA_free(rsa);

	pgp_keyid(keydata->sigid, PGP_KEY_ID_SIZE, &keydata->key.seckey.pubkey, seckey->hash_alg);
	pgp_fingerprint(&keydata->sigfingerprint, &keydata->key.seckey.pubkey, seckey->hash_alg);

	/* Generate checksum */

	output = NULL;
	mem = NULL;

	pgp_setup_memory_write(&output, &mem, 128);

	pgp_push_checksum_writer(output, seckey);

	switch (seckey->pubkey.alg) {
	case PGP_PKA_DSA:
		return pgp_write_mpi(output, seckey->key.dsa.x);
	case PGP_PKA_RSA:
	case PGP_PKA_RSA_ENCRYPT_ONLY:
	case PGP_PKA_RSA_SIGN_ONLY:
		if (!pgp_write_mpi(output, seckey->key.rsa.d) ||
		    !pgp_write_mpi(output, seckey->key.rsa.p) ||
		    !pgp_write_mpi(output, seckey->key.rsa.q) ||
		    !pgp_write_mpi(output, seckey->key.rsa.u)) {
			return 0;
		}
		break;
	case PGP_PKA_ELGAMAL:
		return pgp_write_mpi(output, seckey->key.elgamal.x);

	default:
		(void) fprintf(stderr, "Bad seckey->pubkey.alg\n");
		return 0;
	}

	/* close rather than pop, since its the only one on the stack */
	pgp_writer_close(output);
	pgp_teardown_memory_write(output, mem);

	/* should now have checksum in seckey struct */

	/* test */
	if (pgp_get_debug_level(__FILE__)) {
		test_seckey(seckey);
	}

	return 1;
}
Exemple #8
0
int BN_X931_derive_prime_ex(BIGNUM *p, BIGNUM *p1, BIGNUM *p2,
			const BIGNUM *Xp, const BIGNUM *Xp1, const BIGNUM *Xp2,
			const BIGNUM *e, BN_CTX *ctx, BN_GENCB *cb)
	{
	int ret = 0;

	BIGNUM *t, *p1p2, *pm1;

	/* Only even e supported */
	if (!BN_is_odd(e))
		return 0;

	BN_CTX_start(ctx);
	if (!p1)
		p1 = BN_CTX_get(ctx);

	if (!p2)
		p2 = BN_CTX_get(ctx);

	t = BN_CTX_get(ctx);

	p1p2 = BN_CTX_get(ctx);

	pm1 = BN_CTX_get(ctx);

	if (!bn_x931_derive_pi(p1, Xp1, ctx, cb))
		goto err;

	if (!bn_x931_derive_pi(p2, Xp2, ctx, cb))
		goto err;

	if (!BN_mul(p1p2, p1, p2, ctx))
		goto err;

	/* First set p to value of Rp */

	if (!BN_mod_inverse(p, p2, p1, ctx))
		goto err;

	if (!BN_mul(p, p, p2, ctx))
		goto err;

	if (!BN_mod_inverse(t, p1, p2, ctx))
		goto err;

	if (!BN_mul(t, t, p1, ctx))
		goto err;

	if (!BN_sub(p, p, t))
		goto err;

	if (p->neg && !BN_add(p, p, p1p2))
		goto err;

	/* p now equals Rp */

	if (!BN_mod_sub(p, p, Xp, p1p2, ctx))
		goto err;

	if (!BN_add(p, p, Xp))
		goto err;

	/* p now equals Yp0 */

	for (;;)
		{
		int i = 1;
		BN_GENCB_call(cb, 0, i++);
		if (!BN_copy(pm1, p))
			goto err;
		if (!BN_sub_word(pm1, 1))
			goto err;
		if (!BN_gcd(t, pm1, e, ctx))
			goto err;
		if (BN_is_one(t)
		/* X9.31 specifies 8 MR and 1 Lucas test or any prime test
		 * offering similar or better guarantees 50 MR is considerably 
		 * better.
		 */
			&& BN_is_prime_fasttest_ex(p, 50, ctx, 1, cb))
			break;
		if (!BN_add(p, p, p1p2))
			goto err;
		}

	BN_GENCB_call(cb, 3, 0);

	ret = 1;

	err:

	BN_CTX_end(ctx);

	return ret;
	}
Exemple #9
0
// Perform ECDSA key recovery (see SEC1 4.1.6) for curves over (mod p)-fields
// recid selects which key is recovered
// if check is nonzero, additional checks are performed
int ECDSA_SIG_recover_key_GFp(EC_KEY *eckey, ECDSA_SIG *ecsig, const unsigned char *msg, int msglen, int recid, int check)
{
    if (!eckey) return 0;

    int ret = 0;
    BN_CTX *ctx = NULL;

    BIGNUM *x = NULL;
    BIGNUM *e = NULL;
    BIGNUM *order = NULL;
    BIGNUM *sor = NULL;
    BIGNUM *eor = NULL;
    BIGNUM *field = NULL;
    EC_POINT *R = NULL;
    EC_POINT *O = NULL;
    EC_POINT *Q = NULL;
    BIGNUM *rr = NULL;
    BIGNUM *zero = NULL;
    int n = 0;
    int i = recid / 2;

    const EC_GROUP *group = EC_KEY_get0_group(eckey);
    if ((ctx = BN_CTX_new()) == NULL) { ret = -1; goto err; }
    BN_CTX_start(ctx);
    order = BN_CTX_get(ctx);
    if (!EC_GROUP_get_order(group, order, ctx)) { ret = -2; goto err; }
    x = BN_CTX_get(ctx);
    if (!BN_copy(x, order)) { ret=-1; goto err; }
    if (!BN_mul_word(x, i)) { ret=-1; goto err; }
    if (!BN_add(x, x, ecsig->r)) { ret=-1; goto err; }
    field = BN_CTX_get(ctx);
    if (!EC_GROUP_get_curve_GFp(group, field, NULL, NULL, ctx)) { ret=-2; goto err; }
    if (BN_cmp(x, field) >= 0) { ret=0; goto err; }
    if ((R = EC_POINT_new(group)) == NULL) { ret = -2; goto err; }
    if (!EC_POINT_set_compressed_coordinates_GFp(group, R, x, recid % 2, ctx)) { ret=0; goto err; }
    if (check)
    {
        if ((O = EC_POINT_new(group)) == NULL) { ret = -2; goto err; }
        if (!EC_POINT_mul(group, O, NULL, R, order, ctx)) { ret=-2; goto err; }
        if (!EC_POINT_is_at_infinity(group, O)) { ret = 0; goto err; }
    }
    if ((Q = EC_POINT_new(group)) == NULL) { ret = -2; goto err; }
    n = EC_GROUP_get_degree(group);
    e = BN_CTX_get(ctx);
    if (!BN_bin2bn(msg, msglen, e)) { ret=-1; goto err; }
    if (8*msglen > n) BN_rshift(e, e, 8-(n & 7));
    zero = BN_CTX_get(ctx);
    if (!BN_zero(zero)) { ret=-1; goto err; }
    if (!BN_mod_sub(e, zero, e, order, ctx)) { ret=-1; goto err; }
    rr = BN_CTX_get(ctx);
    if (!BN_mod_inverse(rr, ecsig->r, order, ctx)) { ret=-1; goto err; }
    sor = BN_CTX_get(ctx);
    if (!BN_mod_mul(sor, ecsig->s, rr, order, ctx)) { ret=-1; goto err; }
    eor = BN_CTX_get(ctx);
    if (!BN_mod_mul(eor, e, rr, order, ctx)) { ret=-1; goto err; }
    if (!EC_POINT_mul(group, Q, eor, R, sor, ctx)) { ret=-2; goto err; }
    if (!EC_KEY_set_public_key(eckey, Q)) { ret=-2; goto err; }

    ret = 1;

err:
    if (ctx) {
        BN_CTX_end(ctx);
        BN_CTX_free(ctx);
    }
    if (R != NULL) EC_POINT_free(R);
    if (O != NULL) EC_POINT_free(O);
    if (Q != NULL) EC_POINT_free(Q);
    return ret;
}
static int ecdsa_do_verify(const unsigned char *dgst, int dgst_len,
		const ECDSA_SIG *sig, EC_KEY *eckey)
{
	int ret = -1, i;
	BN_CTX   *ctx;
	BIGNUM   *order, *u1, *u2, *m, *X;
	EC_POINT *point = NULL;
	const EC_GROUP *group;
	const EC_POINT *pub_key;

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

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

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

	if ((point = EC_POINT_new(group)) == NULL)
	{
		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
		goto err;
	}
	if (!EC_POINT_mul(group, point, u1, pub_key, u2, ctx))
	{
		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
		goto err;
	}
	if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field)
	{
		if (!EC_POINT_get_affine_coordinates_GFp(group,
			point, X, NULL, ctx))
		{
			ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
			goto err;
		}
	}
#ifndef OPENSSL_NO_EC2M
	else /* NID_X9_62_characteristic_two_field */
	{
		if (!EC_POINT_get_affine_coordinates_GF2m(group,
			point, X, NULL, ctx))
		{
			ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
			goto err;
		}
	}
#endif	
	if (!BN_nnmod(u1, X, order, ctx))
	{
		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
		goto err;
	}
	/*  if the signature is correct u1 is equal to sig->r */
	ret = (BN_ucmp(u1, sig->r) == 0);
err:
	BN_CTX_end(ctx);
	BN_CTX_free(ctx);
	if (point)
		EC_POINT_free(point);
	return ret;
}
static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
		BIGNUM **rp)
{
	BN_CTX   *ctx = NULL;
	BIGNUM	 *k = NULL, *r = NULL, *order = NULL, *X = NULL;
	EC_POINT *tmp_point=NULL;
	const EC_GROUP *group;
	int 	 ret = 0;

	if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL)
	{
		ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_PASSED_NULL_PARAMETER);
		return 0;
	}

	if (ctx_in == NULL) 
	{
		if ((ctx = BN_CTX_new()) == NULL)
		{
			ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,ERR_R_MALLOC_FAILURE);
			return 0;
		}
	}
	else
		ctx = ctx_in;

	k     = BN_new();	/* this value is later returned in *kinvp */
	r     = BN_new();	/* this value is later returned in *rp    */
	order = BN_new();
	X     = BN_new();
	if (!k || !r || !order || !X)
	{
		ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_MALLOC_FAILURE);
		goto err;
	}
	if ((tmp_point = EC_POINT_new(group)) == NULL)
	{
		ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
		goto err;
	}
	if (!EC_GROUP_get_order(group, order, ctx))
	{
		ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
		goto err;
	}
	
	do
	{
		/* get random k */	
		do
			if (!BN_rand_range(k, order))
			{
				ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,
				 ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED);	
				goto err;
			}
		while (BN_is_zero(k));

		/* We do not want timing information to leak the length of k,
		 * so we compute G*k using an equivalent scalar of fixed
		 * bit-length. */

		if (!BN_add(k, k, order)) goto err;
		if (BN_num_bits(k) <= BN_num_bits(order))
			if (!BN_add(k, k, order)) goto err;

		/* compute r the x-coordinate of generator * k */
		if (!EC_POINT_mul(group, tmp_point, k, NULL, NULL, ctx))
		{
			ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
			goto err;
		}
		if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field)
		{
			if (!EC_POINT_get_affine_coordinates_GFp(group,
				tmp_point, X, NULL, ctx))
			{
				ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,ERR_R_EC_LIB);
				goto err;
			}
		}
#ifndef OPENSSL_NO_EC2M
		else /* NID_X9_62_characteristic_two_field */
		{
			if (!EC_POINT_get_affine_coordinates_GF2m(group,
				tmp_point, X, NULL, ctx))
			{
				ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,ERR_R_EC_LIB);
				goto err;
			}
		}
#endif
		if (!BN_nnmod(r, X, order, ctx))
		{
			ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
			goto err;
		}
	}
	while (BN_is_zero(r));

	/* compute the inverse of k */
	if (!BN_mod_inverse(k, k, order, ctx))
	{
		ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
		goto err;	
	}
	/* clear old values if necessary */
	if (*rp != NULL)
		BN_clear_free(*rp);
	if (*kinvp != NULL) 
		BN_clear_free(*kinvp);
	/* save the pre-computed values  */
	*rp    = r;
	*kinvp = k;
	ret = 1;
err:
	if (!ret)
	{
		if (k != NULL) BN_clear_free(k);
		if (r != NULL) BN_clear_free(r);
	}
	if (ctx_in == NULL) 
		BN_CTX_free(ctx);
	if (order != NULL)
		BN_free(order);
	if (tmp_point != NULL) 
		EC_POINT_free(tmp_point);
	if (X)
		BN_clear_free(X);
	return(ret);
}
Exemple #12
0
int
gost2001_do_verify(BIGNUM *md, ECDSA_SIG *sig, GOST_KEY *ec)
{
	BN_CTX *ctx = BN_CTX_new();
	const EC_GROUP *group = GOST_KEY_get0_group(ec);
	BIGNUM *order;
	BIGNUM *e = NULL, *R = NULL, *v = NULL, *z1 = NULL, *z2 = NULL;
	BIGNUM *X = NULL, *tmp = NULL;
	EC_POINT *C = NULL;
	const EC_POINT *pub_key = NULL;
	int ok = 0;

	if (ctx == NULL)
		goto err;
	BN_CTX_start(ctx);
	if ((order = BN_CTX_get(ctx)) == NULL)
		goto err;
	if ((e = BN_CTX_get(ctx)) == NULL)
		goto err;
	if ((z1 = BN_CTX_get(ctx)) == NULL)
		goto err;
	if ((z2 = BN_CTX_get(ctx)) == NULL)
		goto err;
	if ((tmp = BN_CTX_get(ctx)) == NULL)
		goto err;
	if ((X = BN_CTX_get(ctx)) == NULL)
		goto err;
	if ((R = BN_CTX_get(ctx)) == NULL)
		goto err;
	if ((v = BN_CTX_get(ctx)) == NULL)
		goto err;

	if (EC_GROUP_get_order(group, order, ctx) == 0)
		goto err;
	pub_key = GOST_KEY_get0_public_key(ec);
	if (BN_is_zero(sig->s) || BN_is_zero(sig->r) ||
	    BN_cmp(sig->s, order) >= 1 || BN_cmp(sig->r, order) >= 1) {
		GOSTerr(GOST_F_GOST2001_DO_VERIFY,
		    GOST_R_SIGNATURE_PARTS_GREATER_THAN_Q);
		goto err;
	}

	if (BN_mod(e, md, order, ctx) == 0)
		goto err;
	if (BN_is_zero(e))
		BN_one(e);
	if ((v = BN_mod_inverse(v, e, order, ctx)) == NULL)
		goto err;
	if (BN_mod_mul(z1, sig->s, v, order, ctx) == 0)
		goto err;
	if (BN_sub(tmp, order, sig->r) == 0)
		goto err;
	if (BN_mod_mul(z2, tmp, v, order, ctx) == 0)
		goto err;
	if ((C = EC_POINT_new(group)) == NULL)
		goto err;
	if (EC_POINT_mul(group, C, z1, pub_key, z2, ctx) == 0) {
		GOSTerr(GOST_F_GOST2001_DO_VERIFY, ERR_R_EC_LIB);
		goto err;
	}
	if (EC_POINT_get_affine_coordinates_GFp(group, C, X, NULL, ctx) == 0) {
		GOSTerr(GOST_F_GOST2001_DO_VERIFY, ERR_R_EC_LIB);
		goto err;
	}
	if (BN_mod(R, X, order, ctx) == 0)
		goto err;
	if (BN_cmp(R, sig->r) != 0) {
		GOSTerr(GOST_F_GOST2001_DO_VERIFY, GOST_R_SIGNATURE_MISMATCH);
	} else {
		ok = 1;
	}
err:
	EC_POINT_free(C);
	if (ctx != NULL) {
		BN_CTX_end(ctx);
		BN_CTX_free(ctx);
	}
	return ok;
}
Exemple #13
0
int initRSAKey(RSA *rsa, const char *modulus, const char *exponent, const char *p, const char *q) {

    if(modulus[1] == 'x')
        modulus += 2;

    // Initialize with known key components
    if (!(BN_hex2bn(&rsa->n, modulus)   // public modulus
          && BN_hex2bn(&rsa->e, exponent)  // public exponent
          && BN_dec2bn(&rsa->p, p)         // secret prime factor
          && BN_dec2bn(&rsa->q, q)         // secret prime factor
          )) {
        printf("Error creating RSA key: bignum conversion failed!\n");
    }

	int ok = -1;

    // BIGNUM context for bignum operations
    BN_CTX *ctx = BN_CTX_new();
	if (ctx == NULL) goto err;

	BN_CTX_start(ctx);
	BIGNUM *r0 = BN_CTX_get(ctx);
	BIGNUM *r1 = BN_CTX_get(ctx);
	BIGNUM *r2 = BN_CTX_get(ctx);
	if (r2 == NULL) goto err;

    /* We need the (other) RSA components non-NULL */
	if(!rsa->d && ((rsa->d=BN_new()) == NULL)) goto err;
	if(!rsa->dmp1 && ((rsa->dmp1=BN_new()) == NULL)) goto err;
	if(!rsa->dmq1 && ((rsa->dmq1=BN_new()) == NULL)) goto err;
	if(!rsa->iqmp && ((rsa->iqmp=BN_new()) == NULL)) goto err;

	/* calculate d */
	if (!BN_sub(r1,rsa->p,BN_value_one())) goto err;	/* p-1 */
	if (!BN_sub(r2,rsa->q,BN_value_one())) goto err;	/* q-1 */
	if (!BN_mul(r0,r1,r2,ctx)) goto err;	/* (p-1)(q-1) */
	if (!BN_mod_inverse(rsa->d,rsa->e,r0,ctx)) goto err;	/* d */

    /* calculate d mod (p-1) */
	if (!BN_mod(rsa->dmp1,rsa->d,r1,ctx)) goto err;

	/* calculate d mod (q-1) */
	if (!BN_mod(rsa->dmq1,rsa->d,r2,ctx)) goto err;

	/* calculate inverse of q mod p */
	if (!BN_mod_inverse(rsa->iqmp,rsa->q,rsa->p,ctx)) goto err;

	ok = 1;
err:
	if (ok == -1)
    {
        printf("Error creating RSA key: bignum operation failed!\n");
    }
	if (ctx != NULL)
    {
		BN_CTX_end(ctx);
		BN_CTX_free(ctx);
    }

	return ok;
}
Exemple #14
0
static int dsa_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig,
		  DSA *dsa)
	{
	BN_CTX *ctx;
	BIGNUM u1,u2,t1;
	BN_MONT_CTX *mont=NULL;
	int ret = -1;

	if ((ctx=BN_CTX_new()) == NULL) goto err;
	BN_init(&u1);
	BN_init(&u2);
	BN_init(&t1);

	/* Calculate W = inv(S) mod Q
	 * save W in u2 */
	if ((BN_mod_inverse(&u2,sig->s,dsa->q,ctx)) == NULL) goto err;

	/* save M in u1 */
	if (BN_bin2bn(dgst,dgst_len,&u1) == NULL) goto err;

	/* u1 = M * w mod q */
	if (!BN_mod_mul(&u1,&u1,&u2,dsa->q,ctx)) goto err;

	/* u2 = r * w mod q */
	if (!BN_mod_mul(&u2,sig->r,&u2,dsa->q,ctx)) goto err;

	if ((dsa->method_mont_p == NULL) && (dsa->flags & DSA_FLAG_CACHE_MONT_P))
		{
		if ((dsa->method_mont_p=(char *)BN_MONT_CTX_new()) != NULL)
			if (!BN_MONT_CTX_set((BN_MONT_CTX *)dsa->method_mont_p,
				dsa->p,ctx)) goto err;
		}
	mont=(BN_MONT_CTX *)dsa->method_mont_p;

#if 0
	{
	BIGNUM t2;

	BN_init(&t2);
	/* v = ( g^u1 * y^u2 mod p ) mod q */
	/* let t1 = g ^ u1 mod p */
	if (!BN_mod_exp_mont(&t1,dsa->g,&u1,dsa->p,ctx,mont)) goto err;
	/* let t2 = y ^ u2 mod p */
	if (!BN_mod_exp_mont(&t2,dsa->pub_key,&u2,dsa->p,ctx,mont)) goto err;
	/* let u1 = t1 * t2 mod p */
	if (!BN_mod_mul(&u1,&t1,&t2,dsa->p,ctx)) goto err_bn;
	BN_free(&t2);
	}
	/* let u1 = u1 mod q */
	if (!BN_mod(&u1,&u1,dsa->q,ctx)) goto err;
#else
	{
	if (!dsa->meth->dsa_mod_exp(dsa, &t1,dsa->g,&u1,dsa->pub_key,&u2,
						dsa->p,ctx,mont)) goto err;
	/* BN_copy(&u1,&t1); */
	/* let u1 = u1 mod q */
	if (!BN_mod(&u1,&t1,dsa->q,ctx)) goto err;
	}
#endif
	/* V is now in u1.  If the signature is correct, it will be
	 * equal to R. */
	ret=(BN_ucmp(&u1, sig->r) == 0);

	err:
	if (ret != 1) DSAerr(DSA_F_DSA_DO_VERIFY,ERR_R_BN_LIB);
	if (ctx != NULL) BN_CTX_free(ctx);
	BN_free(&u1);
	BN_free(&u2);
	BN_free(&t1);
	return(ret);
	}
Exemple #15
0
static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value,
                              BN_GENCB *cb)
{
    BIGNUM *r0 = NULL, *r1 = NULL, *r2 = NULL, *r3 = NULL, *tmp;
    BIGNUM local_r0, local_d, local_p;
    BIGNUM *pr0, *d, *p;
    int bitsp, bitsq, ok = -1, n = 0;
    BN_CTX *ctx = NULL;

    /*
     * When generating ridiculously small keys, we can get stuck
     * continually regenerating the same prime values.
     */
    if (bits < 16) {
        ok = 0;             /* we set our own err */
        RSAerr(RSA_F_RSA_BUILTIN_KEYGEN, RSA_R_KEY_SIZE_TOO_SMALL);
        goto err;
    }

    ctx = BN_CTX_new();
    if (ctx == NULL)
        goto err;
    BN_CTX_start(ctx);
    r0 = BN_CTX_get(ctx);
    r1 = BN_CTX_get(ctx);
    r2 = BN_CTX_get(ctx);
    r3 = BN_CTX_get(ctx);
    if (r3 == NULL)
        goto err;

    bitsp = (bits + 1) / 2;
    bitsq = bits - bitsp;

    /* We need the RSA components non-NULL */
    if (!rsa->n && ((rsa->n = BN_new()) == NULL))
        goto err;
    if (!rsa->d && ((rsa->d = BN_new()) == NULL))
        goto err;
    if (!rsa->e && ((rsa->e = BN_new()) == NULL))
        goto err;
    if (!rsa->p && ((rsa->p = BN_new()) == NULL))
        goto err;
    if (!rsa->q && ((rsa->q = BN_new()) == NULL))
        goto err;
    if (!rsa->dmp1 && ((rsa->dmp1 = BN_new()) == NULL))
        goto err;
    if (!rsa->dmq1 && ((rsa->dmq1 = BN_new()) == NULL))
        goto err;
    if (!rsa->iqmp && ((rsa->iqmp = BN_new()) == NULL))
        goto err;

    if (BN_copy(rsa->e, e_value) == NULL)
        goto err;

    /* generate p and q */
    for (;;) {
        if (!BN_generate_prime_ex(rsa->p, bitsp, 0, NULL, NULL, cb))
            goto err;
        if (!BN_sub(r2, rsa->p, BN_value_one()))
            goto err;
        if (!BN_gcd(r1, r2, rsa->e, ctx))
            goto err;
        if (BN_is_one(r1))
            break;
        if (!BN_GENCB_call(cb, 2, n++))
            goto err;
    }
    if (!BN_GENCB_call(cb, 3, 0))
        goto err;
    for (;;) {
        do {
            if (!BN_generate_prime_ex(rsa->q, bitsq, 0, NULL, NULL, cb))
                goto err;
        } while (BN_cmp(rsa->p, rsa->q) == 0);
        if (!BN_sub(r2, rsa->q, BN_value_one()))
            goto err;
        if (!BN_gcd(r1, r2, rsa->e, ctx))
            goto err;
        if (BN_is_one(r1))
            break;
        if (!BN_GENCB_call(cb, 2, n++))
            goto err;
    }
    if (!BN_GENCB_call(cb, 3, 1))
        goto err;
    if (BN_cmp(rsa->p, rsa->q) < 0) {
        tmp = rsa->p;
        rsa->p = rsa->q;
        rsa->q = tmp;
    }

    /* calculate n */
    if (!BN_mul(rsa->n, rsa->p, rsa->q, ctx))
        goto err;

    /* calculate d */
    if (!BN_sub(r1, rsa->p, BN_value_one()))
        goto err;               /* p-1 */
    if (!BN_sub(r2, rsa->q, BN_value_one()))
        goto err;               /* q-1 */
    if (!BN_mul(r0, r1, r2, ctx))
        goto err;               /* (p-1)(q-1) */
    if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) {
        pr0 = &local_r0;
        BN_with_flags(pr0, r0, BN_FLG_CONSTTIME);
    } else
        pr0 = r0;
    if (!BN_mod_inverse(rsa->d, rsa->e, pr0, ctx))
        goto err;               /* d */

    /* set up d for correct BN_FLG_CONSTTIME flag */
    if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) {
        d = &local_d;
        BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME);
    } else
        d = rsa->d;

    /* calculate d mod (p-1) */
    if (!BN_mod(rsa->dmp1, d, r1, ctx))
        goto err;

    /* calculate d mod (q-1) */
    if (!BN_mod(rsa->dmq1, d, r2, ctx))
        goto err;

    /* calculate inverse of q mod p */
    if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) {
        p = &local_p;
        BN_with_flags(p, rsa->p, BN_FLG_CONSTTIME);
    } else
        p = rsa->p;
    if (!BN_mod_inverse(rsa->iqmp, rsa->q, p, ctx))
        goto err;

    ok = 1;
 err:
    if (ok == -1) {
        RSAerr(RSA_F_RSA_BUILTIN_KEYGEN, ERR_LIB_BN);
        ok = 0;
    }
    if (ctx != NULL) {
        BN_CTX_end(ctx);
        BN_CTX_free(ctx);
    }

    return ok;
}
Exemple #16
0
int ECDSA_do_verify(const uint8_t *digest, size_t digest_len,
                    const ECDSA_SIG *sig, EC_KEY *eckey) {
  int ret = 0;
  BN_CTX *ctx;
  BIGNUM *u1, *u2, *m, *X;
  EC_POINT *point = NULL;
  const EC_GROUP *group;
  const EC_POINT *pub_key;

  /* check input values */
  if ((group = EC_KEY_get0_group(eckey)) == NULL ||
      (pub_key = EC_KEY_get0_public_key(eckey)) == NULL ||
      sig == NULL) {
    OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_MISSING_PARAMETERS);
    return 0;
  }

  ctx = BN_CTX_new();
  if (!ctx) {
    OPENSSL_PUT_ERROR(ECDSA, ERR_R_MALLOC_FAILURE);
    return 0;
  }
  BN_CTX_start(ctx);
  u1 = BN_CTX_get(ctx);
  u2 = BN_CTX_get(ctx);
  m = BN_CTX_get(ctx);
  X = BN_CTX_get(ctx);
  if (u1 == NULL || u2 == NULL || m == NULL || X == NULL) {
    OPENSSL_PUT_ERROR(ECDSA, ERR_R_BN_LIB);
    goto err;
  }

  const BIGNUM *order = EC_GROUP_get0_order(group);
  if (BN_is_zero(sig->r) || BN_is_negative(sig->r) ||
      BN_ucmp(sig->r, order) >= 0 || BN_is_zero(sig->s) ||
      BN_is_negative(sig->s) || BN_ucmp(sig->s, order) >= 0) {
    OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_BAD_SIGNATURE);
    ret = 0; /* signature is invalid */
    goto err;
  }
  /* calculate tmp1 = inv(S) mod order */
  if (!BN_mod_inverse(u2, sig->s, order, ctx)) {
    OPENSSL_PUT_ERROR(ECDSA, ERR_R_BN_LIB);
    goto err;
  }
  if (!digest_to_bn(m, digest, digest_len, order)) {
    goto err;
  }
  /* u1 = m * tmp mod order */
  if (!BN_mod_mul(u1, m, u2, order, ctx)) {
    OPENSSL_PUT_ERROR(ECDSA, ERR_R_BN_LIB);
    goto err;
  }
  /* u2 = r * w mod q */
  if (!BN_mod_mul(u2, sig->r, u2, order, ctx)) {
    OPENSSL_PUT_ERROR(ECDSA, ERR_R_BN_LIB);
    goto err;
  }

  point = EC_POINT_new(group);
  if (point == NULL) {
    OPENSSL_PUT_ERROR(ECDSA, ERR_R_MALLOC_FAILURE);
    goto err;
  }
  if (!EC_POINT_mul(group, point, u1, pub_key, u2, ctx)) {
    OPENSSL_PUT_ERROR(ECDSA, ERR_R_EC_LIB);
    goto err;
  }
  if (!EC_POINT_get_affine_coordinates_GFp(group, point, X, NULL, ctx)) {
    OPENSSL_PUT_ERROR(ECDSA, ERR_R_EC_LIB);
    goto err;
  }
  if (!BN_nnmod(u1, X, order, ctx)) {
    OPENSSL_PUT_ERROR(ECDSA, ERR_R_BN_LIB);
    goto err;
  }
  /* if the signature is correct u1 is equal to sig->r */
  ret = (BN_ucmp(u1, sig->r) == 0);

err:
  BN_CTX_end(ctx);
  BN_CTX_free(ctx);
  EC_POINT_free(point);
  return ret;
}
extern "C" void Java_java_math_NativeBN_BN_1mod_1inverse(JNIEnv* env, jclass, jlong ret, jlong a, jlong n) {
  if (!threeValidHandles(env, ret, a, n)) return;
  Unique_BN_CTX ctx(BN_CTX_new());
  BN_mod_inverse(toBigNum(ret), toBigNum(a), toBigNum(n), ctx.get());
  throwExceptionIfNecessary(env);
}
Exemple #18
0
int RSA_recover_crt_params(RSA *rsa) {
  BN_CTX *ctx;
  BIGNUM *totient, *rem, *multiple, *p_plus_q, *p_minus_q;
  int ok = 0;

  if (rsa->n == NULL || rsa->e == NULL || rsa->d == NULL) {
    OPENSSL_PUT_ERROR(RSA, RSA_R_EMPTY_PUBLIC_KEY);
    return 0;
  }

  if (rsa->p || rsa->q || rsa->dmp1 || rsa->dmq1 || rsa->iqmp) {
    OPENSSL_PUT_ERROR(RSA, RSA_R_CRT_PARAMS_ALREADY_GIVEN);
    return 0;
  }

  if (rsa->additional_primes != NULL) {
    OPENSSL_PUT_ERROR(RSA, RSA_R_CANNOT_RECOVER_MULTI_PRIME_KEY);
    return 0;
  }

  /* This uses the algorithm from section 9B of the RSA paper:
   * http://people.csail.mit.edu/rivest/Rsapaper.pdf */

  ctx = BN_CTX_new();
  if (ctx == NULL) {
    OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
    return 0;
  }

  BN_CTX_start(ctx);
  totient = BN_CTX_get(ctx);
  rem = BN_CTX_get(ctx);
  multiple = BN_CTX_get(ctx);
  p_plus_q = BN_CTX_get(ctx);
  p_minus_q = BN_CTX_get(ctx);

  if (totient == NULL || rem == NULL || multiple == NULL || p_plus_q == NULL ||
      p_minus_q == NULL) {
    OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
    goto err;
  }

  /* ed-1 is a small multiple of φ(n). */
  if (!BN_mul(totient, rsa->e, rsa->d, ctx) ||
      !BN_sub_word(totient, 1) ||
      /* φ(n) =
       * pq - p - q + 1 =
       * n - (p + q) + 1
       *
       * Thus n is a reasonable estimate for φ(n). So, (ed-1)/n will be very
       * close. But, when we calculate the quotient, we'll be truncating it
       * because we discard the remainder. Thus (ed-1)/multiple will be >= n,
       * which the totient cannot be. So we add one to the estimate.
       *
       * Consider ed-1 as:
       *
       * multiple * (n - (p+q) + 1) =
       * multiple*n - multiple*(p+q) + multiple
       *
       * When we divide by n, the first term becomes multiple and, since
       * multiple and p+q is tiny compared to n, the second and third terms can
       * be ignored. Thus I claim that subtracting one from the estimate is
       * sufficient. */
      !BN_div(multiple, NULL, totient, rsa->n, ctx) ||
      !BN_add_word(multiple, 1) ||
      !BN_div(totient, rem, totient, multiple, ctx)) {
    OPENSSL_PUT_ERROR(RSA, ERR_R_BN_LIB);
    goto err;
  }

  if (!BN_is_zero(rem)) {
    OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_RSA_PARAMETERS);
    goto err;
  }

  rsa->p = BN_new();
  rsa->q = BN_new();
  rsa->dmp1 = BN_new();
  rsa->dmq1 = BN_new();
  rsa->iqmp = BN_new();
  if (rsa->p == NULL || rsa->q == NULL || rsa->dmp1 == NULL || rsa->dmq1 ==
      NULL || rsa->iqmp == NULL) {
    OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
    goto err;
  }

  /* φ(n) = n - (p + q) + 1 =>
   * n - totient + 1 = p + q */
  if (!BN_sub(p_plus_q, rsa->n, totient) ||
      !BN_add_word(p_plus_q, 1) ||
      /* p - q = sqrt((p+q)^2 - 4n) */
      !BN_sqr(rem, p_plus_q, ctx) ||
      !BN_lshift(multiple, rsa->n, 2) ||
      !BN_sub(rem, rem, multiple) ||
      !BN_sqrt(p_minus_q, rem, ctx) ||
      /* q is 1/2 (p+q)-(p-q) */
      !BN_sub(rsa->q, p_plus_q, p_minus_q) ||
      !BN_rshift1(rsa->q, rsa->q) ||
      !BN_div(rsa->p, NULL, rsa->n, rsa->q, ctx) ||
      !BN_mul(multiple, rsa->p, rsa->q, ctx)) {
    OPENSSL_PUT_ERROR(RSA, ERR_R_BN_LIB);
    goto err;
  }

  if (BN_cmp(multiple, rsa->n) != 0) {
    OPENSSL_PUT_ERROR(RSA, RSA_R_INTERNAL_ERROR);
    goto err;
  }

  if (!BN_sub(rem, rsa->p, BN_value_one()) ||
      !BN_mod(rsa->dmp1, rsa->d, rem, ctx) ||
      !BN_sub(rem, rsa->q, BN_value_one()) ||
      !BN_mod(rsa->dmq1, rsa->d, rem, ctx) ||
      !BN_mod_inverse(rsa->iqmp, rsa->q, rsa->p, ctx)) {
    OPENSSL_PUT_ERROR(RSA, ERR_R_BN_LIB);
    goto err;
  }

  ok = 1;

err:
  BN_CTX_end(ctx);
  BN_CTX_free(ctx);
  if (!ok) {
    bn_free_and_null(&rsa->p);
    bn_free_and_null(&rsa->q);
    bn_free_and_null(&rsa->dmp1);
    bn_free_and_null(&rsa->dmq1);
    bn_free_and_null(&rsa->iqmp);
  }
  return ok;
}