コード例 #1
0
ファイル: ec.c プロジェクト: witchu/lua-openssl
static int openssl_eckey_group(lua_State *L)
{
  const EC_GROUP* g = openssl_get_ec_group(L, 1, 2, 3);
  if (g)
  {
    const EC_POINT* p = EC_GROUP_get0_generator(g);
    p = EC_POINT_dup(p, g);
    PUSH_OBJECT(g, "openssl.ec_group");
    PUSH_OBJECT(p, "openssl.ec_point");
    return 2;
  }
  return 0;
};
コード例 #2
0
ファイル: client.c プロジェクト: ep69/tang
static TANG_MSG *
rec(int sock, EC_KEY *key, const char *file, int line)
{
    TANG_MSG_REC_REQ *req = NULL;
    const EC_GROUP *grp = NULL;
    TANG_MSG *rep = NULL;

    test(grp = EC_KEY_get0_group(key));
    test(req = TANG_MSG_REC_REQ_new());
    test(conv_eckey2gkey(key, TANG_KEY_USE_REC, req->key, NULL) == 0);
    test(conv_point2os(grp, EC_GROUP_get0_generator(grp), req->x, NULL) == 0);
    test(rep = request(sock, &(TANG_MSG) {
        .type = TANG_MSG_TYPE_REC_REQ,
        .val.rec.req = req
    }, file, line));
int example_EC_POINT_mul() {
  /* This example ensures that 10×∞ + G = G, in P-256. */
  EC_GROUP *group = NULL;
  EC_POINT *p = NULL, *result = NULL;
  BIGNUM *n = NULL;
  int ret = 0;
  const EC_POINT *generator;

  group = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1);
  p = EC_POINT_new(group);
  result = EC_POINT_new(group);
  n = BN_new();

  if (p == NULL ||
      result == NULL ||
      group == NULL ||
      n == NULL ||
      !EC_POINT_set_to_infinity(group, p) ||
      !BN_set_word(n, 10)) {
    goto err;
  }

  /* First check that 10×∞ = ∞. */
  if (!EC_POINT_mul(group, result, NULL, p, n, NULL) ||
      !EC_POINT_is_at_infinity(group, result)) {
    goto err;
  }

  generator = EC_GROUP_get0_generator(group);

  /* Now check that 10×∞ + G = G. */
  if (!EC_POINT_mul(group, result, BN_value_one(), p, n, NULL) ||
      EC_POINT_cmp(group, result, generator, NULL) != 0) {
    goto err;
  }

  ret = 1;

err:
  BN_free(n);
  EC_POINT_free(result);
  EC_POINT_free(p);
  EC_GROUP_free(group);

  return ret;
}
コード例 #4
0
ファイル: ec.c プロジェクト: witchu/lua-openssl
static int openssl_ec_group_parse(lua_State*L)
{
  const EC_GROUP* group = CHECK_OBJECT(1, EC_GROUP, "openssl.ec_group");
  const EC_POINT *generator = EC_GROUP_get0_generator(group);
  BN_CTX* ctx = BN_CTX_new();
  BIGNUM *a, *b, *p, *order, *cofactor;

  lua_newtable(L);
  if (generator)
  {
    generator = EC_POINT_dup(generator, group);
    AUXILIAR_SETOBJECT(L, generator, "openssl.ec_point", -1, "generator");
  }

  order = BN_new();
  EC_GROUP_get_order(group, order, ctx);
  AUXILIAR_SETOBJECT(L, order, "openssl.bn", -1, "order");

  cofactor = BN_new();
  EC_GROUP_get_cofactor(group, cofactor, ctx);
  AUXILIAR_SETOBJECT(L, cofactor, "openssl.bn", -1, "cofactor");

  AUXILIAR_SET(L, -1, "asn1_flag", EC_GROUP_get_asn1_flag(group), integer);
  AUXILIAR_SET(L, -1, "degree", EC_GROUP_get_degree(group), integer);
  AUXILIAR_SET(L, -1, "curve_name", EC_GROUP_get_curve_name(group), integer);
  AUXILIAR_SET(L, -1, "conversion_form", EC_GROUP_get_point_conversion_form(group), integer);

  AUXILIAR_SETLSTR(L, -1, "seed", EC_GROUP_get0_seed(group), EC_GROUP_get_seed_len(group));

  a = BN_new();
  b = BN_new();
  p = BN_new();
  EC_GROUP_get_curve_GFp(group, p, a, b, ctx);
  lua_newtable(L);
  {
    AUXILIAR_SETOBJECT(L, p, "openssl.bn", -1, "p");
    AUXILIAR_SETOBJECT(L, a, "openssl.bn", -1, "a");
    AUXILIAR_SETOBJECT(L, b, "openssl.bn", -1, "b");
  }
  lua_setfield(L, -2, "curve");
  BN_CTX_free(ctx);

  return 1;
}
コード例 #5
0
ファイル: mpkgen.c プロジェクト: 9cat/misc
int main(int argc, char **argv)
{
	unsigned char ecprot[128];
	unsigned char pbuf[1024];
	EC_KEY *pkey;
	EC_POINT *ptnew, *ptmpk, *ptz;
	BIGNUM z;
	unsigned char *pend = (unsigned char *) pbuf, *px;
	unsigned char hash1[32], hashz[32];
	int n, zlen;
	
	if(argc < 3) {
		printf("Usage: %s <mpk> <seq>\n", argv[0]);
		exit(1);
		}

	OpenSSL_add_all_algorithms();
	
	strcpy(pbuf, argv[2]);
	strcat(pbuf, ":0:");
	zlen = strlen(pbuf);
	px = pbuf + zlen;
	for(n=0; n < 64; n++)
		px[n] = hex(argv[1][n*2])*16 + hex(argv[1][n*2+1]);
	SHA256(pbuf, zlen+64, hash1);
	SHA256(hash1, sizeof(hash1), hashz);
	BN_init(&z);
	BN_bin2bn(hashz, 32, &z);
	
	pkey = EC_KEY_new_by_curve_name(NID_secp256k1);
	ptmpk = EC_POINT_new(EC_KEY_get0_group(pkey));
	pbuf[zlen-1] = 0x04;
	EC_POINT_oct2point(EC_KEY_get0_group(pkey), ptmpk, pbuf+zlen-1, 65, NULL);
	ptz = EC_POINT_new(EC_KEY_get0_group(pkey));
	EC_POINT_mul(EC_KEY_get0_group(pkey), ptz, NULL, EC_GROUP_get0_generator(EC_KEY_get0_group(pkey)), &z, NULL);
	ptnew = EC_POINT_new(EC_KEY_get0_group(pkey));
	EC_POINT_add(EC_KEY_get0_group(pkey), ptnew, ptmpk, ptz, NULL);
	EC_KEY_set_public_key(pkey, ptnew);
	i2o_ECPublicKey(pkey, &pend);
	b58encode_address(EC_KEY_get0_public_key(pkey), EC_KEY_get0_group(pkey), 0, ecprot);
	printf("%s\n", ecprot);

}
コード例 #6
0
ファイル: ecstresstest.c プロジェクト: Ana06/openssl
static int test_curve(void)
{
    EC_GROUP *group = NULL;
    EC_POINT *point = NULL;
    BIGNUM *result = NULL, *expected_result = NULL;
    int ret = 0;

    /*
     * We currently hard-code P-256, though adaptation to other curves.
     * would be straightforward.
     */
    if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1))
            || !TEST_ptr(point = EC_POINT_dup(EC_GROUP_get0_generator(group),
                                              group))
            || !TEST_ptr(result = walk_curve(group, point, num_repeats)))
        return 0;

    if (print_mode) {
        BN_print(bio_out, result);
        BIO_printf(bio_out, "\n");
        ret = 1;
    } else {
        if (!TEST_true(BN_hex2bn(&expected_result, kP256DefaultResult))
                || !TEST_ptr(expected_result)
                || !TEST_BN_eq(result, expected_result))
            goto err;
        ret = 1;
    }

err:
    EC_GROUP_free(group);
    EC_POINT_free(point);
    BN_free(result);
    BN_free(expected_result);
    return ret;
}
コード例 #7
0
void *
vg_thread_loop(void *arg)
{
	unsigned char hash_buf[128];
	unsigned char *eckey_buf;
	unsigned char hash1[32];

	int i, c, len, output_interval;
	int hash_len;

	const BN_ULONG rekey_max = 10000000;
	BN_ULONG npoints, rekey_at, nbatch;

	vg_context_t *vcp = (vg_context_t *) arg;
	EC_KEY *pkey = NULL;
	const EC_GROUP *pgroup;
	const EC_POINT *pgen;
	const int ptarraysize = 256;
	EC_POINT *ppnt[ptarraysize];
	EC_POINT *pbatchinc;

	vg_test_func_t test_func = vcp->vc_test;
	vg_exec_context_t ctx;
	vg_exec_context_t *vxcp;

	struct timeval tvstart;


	memset(&ctx, 0, sizeof(ctx));
	vxcp = &ctx;

	vg_exec_context_init(vcp, &ctx);

	pkey = vxcp->vxc_key;
	pgroup = EC_KEY_get0_group(pkey);
	pgen = EC_GROUP_get0_generator(pgroup);

	for (i = 0; i < ptarraysize; i++) {
		ppnt[i] = EC_POINT_new(pgroup);
		if (!ppnt[i]) {
			fprintf(stderr, "ERROR: out of memory?\n");
			exit(1);
		}
	}
	pbatchinc = EC_POINT_new(pgroup);
	if (!pbatchinc) {
		fprintf(stderr, "ERROR: out of memory?\n");
		exit(1);
	}

	BN_set_word(&vxcp->vxc_bntmp, ptarraysize);
	EC_POINT_mul(pgroup, pbatchinc, &vxcp->vxc_bntmp, NULL, NULL,
		     vxcp->vxc_bnctx);
	EC_POINT_make_affine(pgroup, pbatchinc, vxcp->vxc_bnctx);

	npoints = 0;
	rekey_at = 0;
	nbatch = 0;
	vxcp->vxc_key = pkey;
	vxcp->vxc_binres[0] = vcp->vc_addrtype;
	c = 0;
	output_interval = 1000;
	gettimeofday(&tvstart, NULL);

	if (vcp->vc_format == VCF_SCRIPT) {
		hash_buf[ 0] = 0x51;  // OP_1
		hash_buf[ 1] = 0x41;  // pubkey length
		// gap for pubkey
		hash_buf[67] = 0x51;  // OP_1
		hash_buf[68] = 0xae;  // OP_CHECKMULTISIG
		eckey_buf = hash_buf + 2;
		hash_len = 69;

	} else {
		eckey_buf = hash_buf;
		hash_len = 65;
	}

	while (!vcp->vc_halt) {
		if (++npoints >= rekey_at) {
			vg_exec_context_upgrade_lock(vxcp);
			/* Generate a new random private key */
			EC_KEY_generate_key(pkey);
			npoints = 0;

			/* Determine rekey interval */
			EC_GROUP_get_order(pgroup, &vxcp->vxc_bntmp,
					   vxcp->vxc_bnctx);
			BN_sub(&vxcp->vxc_bntmp2,
			       &vxcp->vxc_bntmp,
			       EC_KEY_get0_private_key(pkey));
			rekey_at = BN_get_word(&vxcp->vxc_bntmp2);
			if ((rekey_at == BN_MASK2) || (rekey_at > rekey_max))
				rekey_at = rekey_max;
			assert(rekey_at > 0);

			EC_POINT_copy(ppnt[0], EC_KEY_get0_public_key(pkey));
			vg_exec_context_downgrade_lock(vxcp);

			npoints++;
			vxcp->vxc_delta = 0;

			if (vcp->vc_pubkey_base)
				EC_POINT_add(pgroup,
					     ppnt[0],
					     ppnt[0],
					     vcp->vc_pubkey_base,
					     vxcp->vxc_bnctx);

			for (nbatch = 1;
			     (nbatch < ptarraysize) && (npoints < rekey_at);
			     nbatch++, npoints++) {
				EC_POINT_add(pgroup,
					     ppnt[nbatch],
					     ppnt[nbatch-1],
					     pgen, vxcp->vxc_bnctx);
			}

		} else {
			/*
			 * Common case
			 *
			 * EC_POINT_add() can skip a few multiplies if
			 * one or both inputs are affine (Z_is_one).
			 * This is the case for every point in ppnt, as
			 * well as pbatchinc.
			 */
			assert(nbatch == ptarraysize);
			for (nbatch = 0;
			     (nbatch < ptarraysize) && (npoints < rekey_at);
			     nbatch++, npoints++) {
				EC_POINT_add(pgroup,
					     ppnt[nbatch],
					     ppnt[nbatch],
					     pbatchinc,
					     vxcp->vxc_bnctx);
			}
		}

		/*
		 * The single most expensive operation performed in this
		 * loop is modular inversion of ppnt->Z.  There is an
		 * algorithm implemented in OpenSSL to do batched inversion
		 * that only does one actual BN_mod_inverse(), and saves
		 * a _lot_ of time.
		 *
		 * To take advantage of this, we batch up a few points,
		 * and feed them to EC_POINTs_make_affine() below.
		 */

		EC_POINTs_make_affine(pgroup, nbatch, ppnt, vxcp->vxc_bnctx);

		for (i = 0; i < nbatch; i++, vxcp->vxc_delta++) {
			/* Hash the public key */
			len = EC_POINT_point2oct(pgroup, ppnt[i],
						 POINT_CONVERSION_UNCOMPRESSED,
						 eckey_buf,
						 65,
						 vxcp->vxc_bnctx);
			assert(len == 65);

			SHA256(hash_buf, hash_len, hash1);
			RIPEMD160(hash1, sizeof(hash1), &vxcp->vxc_binres[1]);

			switch (test_func(vxcp)) {
			case 1:
				npoints = 0;
				rekey_at = 0;
				i = nbatch;
				break;
			case 2:
				goto out;
			default:
				break;
			}
		}

		c += i;
		if (c >= output_interval) {
			output_interval = vg_output_timing(vcp, c, &tvstart);
			if (output_interval > 250000)
				output_interval = 250000;
			c = 0;
		}

		vg_exec_context_yield(vxcp);
	}

out:
	vg_exec_context_del(&ctx);
	vg_context_thread_exit(vcp);

	for (i = 0; i < ptarraysize; i++)
		if (ppnt[i])
			EC_POINT_free(ppnt[i]);
	if (pbatchinc)
		EC_POINT_free(pbatchinc);
	return NULL;
}
コード例 #8
0
ファイル: ec_ameth.c プロジェクト: RyunosukeOno/rayjack
static int eckey_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8)
	{
	const unsigned char *p = NULL;
	void *pval;
	int ptype, pklen;
	EC_KEY *eckey = NULL;
	X509_ALGOR *palg;

	if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8))
		return 0;
	X509_ALGOR_get0(NULL, &ptype, &pval, palg);

	eckey = eckey_type2param(ptype, pval);

	if (!eckey)
		goto ecliberr;

	/* We have parameters now set private key */
	if (!d2i_ECPrivateKey(&eckey, &p, pklen))
		{
		ECerr(EC_F_ECKEY_PRIV_DECODE, EC_R_DECODE_ERROR);
		goto ecerr;
		}

	/* calculate public key (if necessary) */
	if (EC_KEY_get0_public_key(eckey) == NULL)
		{
		const BIGNUM *priv_key;
		const EC_GROUP *group;
		EC_POINT *pub_key;
		/* the public key was not included in the SEC1 private
		 * key => calculate the public key */
		group   = EC_KEY_get0_group(eckey);
		pub_key = EC_POINT_new(group);
		if (pub_key == NULL)
			{
			ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB);
			goto ecliberr;
			}
		if (!EC_POINT_copy(pub_key, EC_GROUP_get0_generator(group)))
			{
			EC_POINT_free(pub_key);
			ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB);
			goto ecliberr;
			}
		priv_key = EC_KEY_get0_private_key(eckey);
		if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, NULL))
			{
			EC_POINT_free(pub_key);
			ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB);
			goto ecliberr;
			}
		if (EC_KEY_set_public_key(eckey, pub_key) == 0)
			{
			EC_POINT_free(pub_key);
			ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB);
			goto ecliberr;
			}
		EC_POINT_free(pub_key);
		}

	EVP_PKEY_assign_EC_KEY(pkey, eckey);
	return 1;

	ecliberr:
	ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB);
	ecerr:
	if (eckey)
		EC_KEY_free(eckey);
	return 0;
	}
コード例 #9
0
ファイル: ec_lib.c プロジェクト: Castaglia/openssl
int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx)
{
    int r = 0;
    BIGNUM *a1, *a2, *a3, *b1, *b2, *b3;
    BN_CTX *ctx_new = NULL;

    /* compare the field types */
    if (EC_METHOD_get_field_type(EC_GROUP_method_of(a)) !=
        EC_METHOD_get_field_type(EC_GROUP_method_of(b)))
        return 1;
    /* compare the curve name (if present in both) */
    if (EC_GROUP_get_curve_name(a) && EC_GROUP_get_curve_name(b) &&
        EC_GROUP_get_curve_name(a) != EC_GROUP_get_curve_name(b))
        return 1;
    if (a->meth->flags & EC_FLAGS_CUSTOM_CURVE)
        return 0;

    if (ctx == NULL)
        ctx_new = ctx = BN_CTX_new();
    if (ctx == NULL)
        return -1;

    BN_CTX_start(ctx);
    a1 = BN_CTX_get(ctx);
    a2 = BN_CTX_get(ctx);
    a3 = BN_CTX_get(ctx);
    b1 = BN_CTX_get(ctx);
    b2 = BN_CTX_get(ctx);
    b3 = BN_CTX_get(ctx);
    if (b3 == NULL) {
        BN_CTX_end(ctx);
        BN_CTX_free(ctx_new);
        return -1;
    }

    /*
     * XXX This approach assumes that the external representation of curves
     * over the same field type is the same.
     */
    if (!a->meth->group_get_curve(a, a1, a2, a3, ctx) ||
        !b->meth->group_get_curve(b, b1, b2, b3, ctx))
        r = 1;

    if (r || BN_cmp(a1, b1) || BN_cmp(a2, b2) || BN_cmp(a3, b3))
        r = 1;

    /* XXX EC_POINT_cmp() assumes that the methods are equal */
    if (r || EC_POINT_cmp(a, EC_GROUP_get0_generator(a),
                          EC_GROUP_get0_generator(b), ctx))
        r = 1;

    if (!r) {
        const BIGNUM *ao, *bo, *ac, *bc;
        /* compare the order and cofactor */
        ao = EC_GROUP_get0_order(a);
        bo = EC_GROUP_get0_order(b);
        ac = EC_GROUP_get0_cofactor(a);
        bc = EC_GROUP_get0_cofactor(b);
        if (ao == NULL || bo == NULL) {
            BN_CTX_end(ctx);
            BN_CTX_free(ctx_new);
            return -1;
        }
        if (BN_cmp(ao, bo) || BN_cmp(ac, bc))
            r = 1;
    }

    BN_CTX_end(ctx);
    BN_CTX_free(ctx_new);

    return r;
}
コード例 #10
0
ファイル: eck_prn.c プロジェクト: 2trill2spill/nextgen
int 
ECPKParameters_print(BIO * bp, const EC_GROUP * x, int off)
{
	unsigned char *buffer = NULL;
	size_t buf_len = 0, i;
	int ret = 0, reason = ERR_R_BIO_LIB;
	BN_CTX *ctx = NULL;
	const EC_POINT *point = NULL;
	BIGNUM *p = NULL, *a = NULL, *b = NULL, *gen = NULL, *order = NULL,
	*cofactor = NULL;
	const unsigned char *seed;
	size_t seed_len = 0;
	const char *nname;

	static const char *gen_compressed = "Generator (compressed):";
	static const char *gen_uncompressed = "Generator (uncompressed):";
	static const char *gen_hybrid = "Generator (hybrid):";

	if (!x) {
		reason = ERR_R_PASSED_NULL_PARAMETER;
		goto err;
	}
	ctx = BN_CTX_new();
	if (ctx == NULL) {
		reason = ERR_R_MALLOC_FAILURE;
		goto err;
	}
	if (EC_GROUP_get_asn1_flag(x)) {
		/* the curve parameter are given by an asn1 OID */
		int nid;

		if (!BIO_indent(bp, off, 128))
			goto err;

		nid = EC_GROUP_get_curve_name(x);
		if (nid == 0)
			goto err;

		if (BIO_printf(bp, "ASN1 OID: %s", OBJ_nid2sn(nid)) <= 0)
			goto err;
		if (BIO_printf(bp, "\n") <= 0)
			goto err;

		nname = EC_curve_nid2nist(nid);
		if (nname) {
			if (!BIO_indent(bp, off, 128))
				goto err;
			if (BIO_printf(bp, "NIST CURVE: %s\n", nname) <= 0)
				goto err;
		}
	} else {
		/* explicit parameters */
		int is_char_two = 0;
		point_conversion_form_t form;
		int tmp_nid = EC_METHOD_get_field_type(EC_GROUP_method_of(x));

		if (tmp_nid == NID_X9_62_characteristic_two_field)
			is_char_two = 1;

		if ((p = BN_new()) == NULL || (a = BN_new()) == NULL ||
		    (b = BN_new()) == NULL || (order = BN_new()) == NULL ||
		    (cofactor = BN_new()) == NULL) {
			reason = ERR_R_MALLOC_FAILURE;
			goto err;
		}
#ifndef OPENSSL_NO_EC2M
		if (is_char_two) {
			if (!EC_GROUP_get_curve_GF2m(x, p, a, b, ctx)) {
				reason = ERR_R_EC_LIB;
				goto err;
			}
		} else		/* prime field */
#endif
		{
			if (!EC_GROUP_get_curve_GFp(x, p, a, b, ctx)) {
				reason = ERR_R_EC_LIB;
				goto err;
			}
		}

		if ((point = EC_GROUP_get0_generator(x)) == NULL) {
			reason = ERR_R_EC_LIB;
			goto err;
		}
		if (!EC_GROUP_get_order(x, order, NULL) ||
		    !EC_GROUP_get_cofactor(x, cofactor, NULL)) {
			reason = ERR_R_EC_LIB;
			goto err;
		}
		form = EC_GROUP_get_point_conversion_form(x);

		if ((gen = EC_POINT_point2bn(x, point,
			    form, NULL, ctx)) == NULL) {
			reason = ERR_R_EC_LIB;
			goto err;
		}
		buf_len = (size_t) BN_num_bytes(p);
		if (buf_len < (i = (size_t) BN_num_bytes(a)))
			buf_len = i;
		if (buf_len < (i = (size_t) BN_num_bytes(b)))
			buf_len = i;
		if (buf_len < (i = (size_t) BN_num_bytes(gen)))
			buf_len = i;
		if (buf_len < (i = (size_t) BN_num_bytes(order)))
			buf_len = i;
		if (buf_len < (i = (size_t) BN_num_bytes(cofactor)))
			buf_len = i;

		if ((seed = EC_GROUP_get0_seed(x)) != NULL)
			seed_len = EC_GROUP_get_seed_len(x);

		buf_len += 10;
		if ((buffer = malloc(buf_len)) == NULL) {
			reason = ERR_R_MALLOC_FAILURE;
			goto err;
		}
		if (!BIO_indent(bp, off, 128))
			goto err;

		/* print the 'short name' of the field type */
		if (BIO_printf(bp, "Field Type: %s\n", OBJ_nid2sn(tmp_nid))
		    <= 0)
			goto err;

		if (is_char_two) {
			/* print the 'short name' of the base type OID */
			int basis_type = EC_GROUP_get_basis_type(x);
			if (basis_type == 0)
				goto err;

			if (!BIO_indent(bp, off, 128))
				goto err;

			if (BIO_printf(bp, "Basis Type: %s\n",
				OBJ_nid2sn(basis_type)) <= 0)
				goto err;

			/* print the polynomial */
			if ((p != NULL) && !ASN1_bn_print(bp, "Polynomial:", p, buffer,
				off))
				goto err;
		} else {
			if ((p != NULL) && !ASN1_bn_print(bp, "Prime:", p, buffer, off))
				goto err;
		}
		if ((a != NULL) && !ASN1_bn_print(bp, "A:   ", a, buffer, off))
			goto err;
		if ((b != NULL) && !ASN1_bn_print(bp, "B:   ", b, buffer, off))
			goto err;
		if (form == POINT_CONVERSION_COMPRESSED) {
			if ((gen != NULL) && !ASN1_bn_print(bp, gen_compressed, gen,
				buffer, off))
				goto err;
		} else if (form == POINT_CONVERSION_UNCOMPRESSED) {
			if ((gen != NULL) && !ASN1_bn_print(bp, gen_uncompressed, gen,
				buffer, off))
				goto err;
		} else {	/* form == POINT_CONVERSION_HYBRID */
			if ((gen != NULL) && !ASN1_bn_print(bp, gen_hybrid, gen,
				buffer, off))
				goto err;
		}
		if ((order != NULL) && !ASN1_bn_print(bp, "Order: ", order,
			buffer, off))
			goto err;
		if ((cofactor != NULL) && !ASN1_bn_print(bp, "Cofactor: ", cofactor,
			buffer, off))
			goto err;
		if (seed && !print_bin(bp, "Seed:", seed, seed_len, off))
			goto err;
	}
	ret = 1;
err:
	if (!ret)
		ECerror(reason);
	BN_free(p);
	BN_free(a);
	BN_free(b);
	BN_free(gen);
	BN_free(order);
	BN_free(cofactor);
	BN_CTX_free(ctx);
	free(buffer);
	return (ret);
}
コード例 #11
0
EVP_PKEY *EVP_PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8)
{
  EVP_PKEY *pkey = NULL;
#ifndef OPENSSL_NO_RSA
  RSA *rsa = NULL;
#endif
#ifndef OPENSSL_NO_DSA
  DSA *dsa = NULL;
  ASN1_TYPE *t1, *t2;
  ASN1_INTEGER *privkey;
  STACK_OF(ASN1_TYPE) *ndsa = NULL;
#endif
#ifndef OPENSSL_NO_EC
  EC_KEY *eckey = NULL;
  const unsigned char *p_tmp;
#endif
#if !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_EC)
  ASN1_TYPE    *param = NULL;  
  BN_CTX *ctx = NULL;
  int plen;
#endif
  X509_ALGOR *a;
  const unsigned char *p;
  const unsigned char *cp;
  int pkeylen;
  int  nid;
  char obj_tmp[80];

  if(p8->pkey->type == V_ASN1_OCTET_STRING) {
    p8->broken = PKCS8_OK;
    p = p8->pkey->value.octet_string->data;
    pkeylen = p8->pkey->value.octet_string->length;
  } else {
    p8->broken = PKCS8_NO_OCTET;
    p = p8->pkey->value.sequence->data;
    pkeylen = p8->pkey->value.sequence->length;
  }
  if (!(pkey = EVP_PKEY_new())) {
    EVPerr(EVP_F_EVP_PKCS82PKEY,ERR_R_MALLOC_FAILURE);
    return NULL;
  }
  a = p8->pkeyalg;
  nid = OBJ_obj2nid(a->algorithm);
  switch(nid)
  {
#ifndef OPENSSL_NO_RSA
    case NID_rsaEncryption:
    cp = p;
    if (!(rsa = d2i_RSAPrivateKey (NULL,&cp, pkeylen))) {
      EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
      return NULL;
    }
    EVP_PKEY_assign_RSA (pkey, rsa);
    break;
#endif
#ifndef OPENSSL_NO_DSA
    case NID_dsa:
    /* PKCS#8 DSA is weird: you just get a private key integer
           * and parameters in the AlgorithmIdentifier the pubkey must
     * be recalculated.
     */
  
    /* Check for broken DSA PKCS#8, UGH! */
    if(*p == (V_ASN1_SEQUENCE|V_ASN1_CONSTRUCTED)) {
        if(!(ndsa = ASN1_seq_unpack_ASN1_TYPE(p, pkeylen, 
                d2i_ASN1_TYPE,
                ASN1_TYPE_free))) {
      EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
      goto dsaerr;
        }
        if(sk_ASN1_TYPE_num(ndsa) != 2 ) {
      EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
      goto dsaerr;
        }
        /* Handle Two broken types:
         * SEQUENCE {parameters, priv_key}
         * SEQUENCE {pub_key, priv_key}
         */

        t1 = sk_ASN1_TYPE_value(ndsa, 0);
        t2 = sk_ASN1_TYPE_value(ndsa, 1);
        if(t1->type == V_ASN1_SEQUENCE) {
      p8->broken = PKCS8_EMBEDDED_PARAM;
      param = t1;
        } else if(a->parameter->type == V_ASN1_SEQUENCE) {
      p8->broken = PKCS8_NS_DB;
      param = a->parameter;
        } else {
      EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
      goto dsaerr;
        }

        if(t2->type != V_ASN1_INTEGER) {
      EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
      goto dsaerr;
        }
        privkey = t2->value.integer;
    } else {
      if (!(privkey=d2i_ASN1_INTEGER (NULL, &p, pkeylen))) {
        EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
        goto dsaerr;
      }
      param = p8->pkeyalg->parameter;
    }
    if (!param || (param->type != V_ASN1_SEQUENCE)) {
      EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
      goto dsaerr;
    }
    cp = p = param->value.sequence->data;
    plen = param->value.sequence->length;
    if (!(dsa = d2i_DSAparams (NULL, &cp, plen))) {
      EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
      goto dsaerr;
    }
    /* We have parameters now set private key */
    if (!(dsa->priv_key = ASN1_INTEGER_to_BN(privkey, NULL))) {
      EVPerr(EVP_F_EVP_PKCS82PKEY,EVP_R_BN_DECODE_ERROR);
      goto dsaerr;
    }
    /* Calculate public key (ouch!) */
    if (!(dsa->pub_key = BN_new())) {
      EVPerr(EVP_F_EVP_PKCS82PKEY,ERR_R_MALLOC_FAILURE);
      goto dsaerr;
    }
    if (!(ctx = BN_CTX_new())) {
      EVPerr(EVP_F_EVP_PKCS82PKEY,ERR_R_MALLOC_FAILURE);
      goto dsaerr;
    }
      
    if (!BN_mod_exp(dsa->pub_key, dsa->g,
             dsa->priv_key, dsa->p, ctx)) {
      
      EVPerr(EVP_F_EVP_PKCS82PKEY,EVP_R_BN_PUBKEY_ERROR);
      goto dsaerr;
    }

    EVP_PKEY_assign_DSA(pkey, dsa);
    BN_CTX_free (ctx);
    if(ndsa) sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
    else ASN1_INTEGER_free(privkey);
    break;
    dsaerr:
    BN_CTX_free (ctx);
    sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
    DSA_free(dsa);
    EVP_PKEY_free(pkey);
    return NULL;
    break;
#endif
#ifndef OPENSSL_NO_EC
    case NID_X9_62_id_ecPublicKey:
    p_tmp = p;
    /* extract the ec parameters */
    param = p8->pkeyalg->parameter;

    if (!param || ((param->type != V_ASN1_SEQUENCE) &&
        (param->type != V_ASN1_OBJECT)))
    {
      EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
      goto ecerr;
    }

    if (param->type == V_ASN1_SEQUENCE)
    {
      cp = p = param->value.sequence->data;
      plen = param->value.sequence->length;

      if (!(eckey = d2i_ECParameters(NULL, &cp, plen)))
      {
        EVPerr(EVP_F_EVP_PKCS82PKEY,
          EVP_R_DECODE_ERROR);
        goto ecerr;
      }
    }
    else
    {
      EC_GROUP *group;
      cp = p = param->value.object->data;
      plen = param->value.object->length;

      /* type == V_ASN1_OBJECT => the parameters are given
       * by an asn1 OID
       */
      if ((eckey = EC_KEY_new()) == NULL)
      {
        EVPerr(EVP_F_EVP_PKCS82PKEY,
          ERR_R_MALLOC_FAILURE);
        goto ecerr;
      }
      group = EC_GROUP_new_by_curve_name(OBJ_obj2nid(a->parameter->value.object));
      if (group == NULL)
        goto ecerr;
      EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
      if (EC_KEY_set_group(eckey, group) == 0)
        goto ecerr;
      EC_GROUP_free(group);
    }

    /* We have parameters now set private key */
    if (!d2i_ECPrivateKey(&eckey, &p_tmp, pkeylen))
    {
      EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
      goto ecerr;
    }

    /* calculate public key (if necessary) */
    if (EC_KEY_get0_public_key(eckey) == NULL)
    {
      const BIGNUM *priv_key;
      const EC_GROUP *group;
      EC_POINT *pub_key;
      /* the public key was not included in the SEC1 private
       * key => calculate the public key */
      group   = EC_KEY_get0_group(eckey);
      pub_key = EC_POINT_new(group);
      if (pub_key == NULL)
      {
        EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_EC_LIB);
        goto ecerr;
      }
      if (!EC_POINT_copy(pub_key, EC_GROUP_get0_generator(group)))
      {
        EC_POINT_free(pub_key);
        EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_EC_LIB);
        goto ecerr;
      }
      priv_key = EC_KEY_get0_private_key(eckey);
      if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, ctx))
      {
        EC_POINT_free(pub_key);
        EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_EC_LIB);
        goto ecerr;
      }
      if (EC_KEY_set_public_key(eckey, pub_key) == 0)
      {
        EC_POINT_free(pub_key);
        EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_EC_LIB);
        goto ecerr;
      }
      EC_POINT_free(pub_key);
    }

    EVP_PKEY_assign_EC_KEY(pkey, eckey);
    if (ctx)
      BN_CTX_free(ctx);
    break;
ecerr:
    if (ctx)
      BN_CTX_free(ctx);
    if (eckey)
      EC_KEY_free(eckey);
    if (pkey)
      EVP_PKEY_free(pkey);
    return NULL;
#endif
    default:
    EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM);
    if (!a->algorithm) BUF_strlcpy (obj_tmp, "NULL", sizeof obj_tmp);
    else i2t_ASN1_OBJECT(obj_tmp, 80, a->algorithm);
    ERR_add_error_data(2, "TYPE=", obj_tmp);
    EVP_PKEY_free (pkey);
    return NULL;
  }
  return pkey;
}
コード例 #12
0
ファイル: ecparam.c プロジェクト: 375670450/openssl
int ecparam_main(int argc, char **argv)
{
    BIGNUM *ec_gen = NULL, *ec_order = NULL, *ec_cofactor = NULL;
    BIGNUM *ec_p = NULL, *ec_a = NULL, *ec_b = NULL;
    BIO *in = NULL, *out = NULL;
    EC_GROUP *group = NULL;
    point_conversion_form_t form = POINT_CONVERSION_UNCOMPRESSED;
    char *curve_name = NULL, *inrand = NULL;
    char *infile = NULL, *outfile = NULL, *prog;
    unsigned char *buffer = NULL;
    OPTION_CHOICE o;
    int asn1_flag = OPENSSL_EC_NAMED_CURVE, new_asn1_flag = 0;
    int informat = FORMAT_PEM, outformat = FORMAT_PEM, noout = 0, C = 0, ret =
        1;
    int list_curves = 0, no_seed = 0, check = 0, new_form = 0;
    int text = 0, i, need_rand = 0, genkey = 0;

    prog = opt_init(argc, argv, ecparam_options);
    while ((o = opt_next()) != OPT_EOF) {
        switch (o) {
        case OPT_EOF:
        case OPT_ERR:
 opthelp:
            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
            goto end;
        case OPT_HELP:
            opt_help(ecparam_options);
            ret = 0;
            goto end;
        case OPT_INFORM:
            if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &informat))
                goto opthelp;
            break;
        case OPT_IN:
            infile = opt_arg();
            break;
        case OPT_OUTFORM:
            if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &outformat))
                goto opthelp;
            break;
        case OPT_OUT:
            outfile = opt_arg();
            break;
        case OPT_TEXT:
            text = 1;
            break;
        case OPT_C:
            C = 1;
            break;
        case OPT_CHECK:
            check = 1;
            break;
        case OPT_LIST_CURVES:
            list_curves = 1;
            break;
        case OPT_NO_SEED:
            no_seed = 1;
            break;
        case OPT_NOOUT:
            noout = 1;
            break;
        case OPT_NAME:
            curve_name = opt_arg();
            break;
        case OPT_CONV_FORM:
            if (!opt_pair(opt_arg(), forms, &new_form))
                goto opthelp;
            form = new_form;
            new_form = 1;
            break;
        case OPT_PARAM_ENC:
            if (!opt_pair(opt_arg(), encodings, &asn1_flag))
                goto opthelp;
            new_asn1_flag = 1;
            break;
        case OPT_GENKEY:
            genkey = need_rand = 1;
            break;
        case OPT_RAND:
            inrand = opt_arg();
            need_rand = 1;
            break;
        case OPT_ENGINE:
            (void)setup_engine(opt_arg(), 0);
            break;
        }
    }
    argc = opt_num_rest();
    argv = opt_rest();

    in = bio_open_default(infile, RB(informat));
    if (in == NULL)
        goto end;
    out = bio_open_default(outfile, WB(outformat));
    if (out == NULL)
        goto end;

    if (list_curves) {
        EC_builtin_curve *curves = NULL;
        size_t crv_len = EC_get_builtin_curves(NULL, 0);
        size_t n;

        curves = app_malloc((int)sizeof(*curves) * crv_len, "list curves");
        if (!EC_get_builtin_curves(curves, crv_len)) {
            OPENSSL_free(curves);
            goto end;
        }

        for (n = 0; n < crv_len; n++) {
            const char *comment;
            const char *sname;
            comment = curves[n].comment;
            sname = OBJ_nid2sn(curves[n].nid);
            if (comment == NULL)
                comment = "CURVE DESCRIPTION NOT AVAILABLE";
            if (sname == NULL)
                sname = "";

            BIO_printf(out, "  %-10s: ", sname);
            BIO_printf(out, "%s\n", comment);
        }

        OPENSSL_free(curves);
        ret = 0;
        goto end;
    }

    if (curve_name != NULL) {
        int nid;

        /*
         * workaround for the SECG curve names secp192r1 and secp256r1 (which
         * are the same as the curves prime192v1 and prime256v1 defined in
         * X9.62)
         */
        if (strcmp(curve_name, "secp192r1") == 0) {
            BIO_printf(bio_err, "using curve name prime192v1 "
                       "instead of secp192r1\n");
            nid = NID_X9_62_prime192v1;
        } else if (strcmp(curve_name, "secp256r1") == 0) {
            BIO_printf(bio_err, "using curve name prime256v1 "
                       "instead of secp256r1\n");
            nid = NID_X9_62_prime256v1;
        } else
            nid = OBJ_sn2nid(curve_name);

        if (nid == 0)
            nid = EC_curve_nist2nid(curve_name);

        if (nid == 0) {
            BIO_printf(bio_err, "unknown curve name (%s)\n", curve_name);
            goto end;
        }

        group = EC_GROUP_new_by_curve_name(nid);
        if (group == NULL) {
            BIO_printf(bio_err, "unable to create curve (%s)\n", curve_name);
            goto end;
        }
        EC_GROUP_set_asn1_flag(group, asn1_flag);
        EC_GROUP_set_point_conversion_form(group, form);
    } else if (informat == FORMAT_ASN1)
        group = d2i_ECPKParameters_bio(in, NULL);
    else
        group = PEM_read_bio_ECPKParameters(in, NULL, NULL, NULL);
    if (group == NULL) {
        BIO_printf(bio_err, "unable to load elliptic curve parameters\n");
        ERR_print_errors(bio_err);
        goto end;
    }

    if (new_form)
        EC_GROUP_set_point_conversion_form(group, form);

    if (new_asn1_flag)
        EC_GROUP_set_asn1_flag(group, asn1_flag);

    if (no_seed) {
        EC_GROUP_set_seed(group, NULL, 0);
    }

    if (text) {
        if (!ECPKParameters_print(out, group, 0))
            goto end;
    }

    if (check) {
        if (group == NULL)
            BIO_printf(bio_err, "no elliptic curve parameters\n");
        BIO_printf(bio_err, "checking elliptic curve parameters: ");
        if (!EC_GROUP_check(group, NULL)) {
            BIO_printf(bio_err, "failed\n");
            ERR_print_errors(bio_err);
        } else
            BIO_printf(bio_err, "ok\n");

    }

    if (C) {
        size_t buf_len = 0, tmp_len = 0;
        const EC_POINT *point;
        int is_prime, len = 0;
        const EC_METHOD *meth = EC_GROUP_method_of(group);

        if ((ec_p = BN_new()) == NULL
                || (ec_a = BN_new()) == NULL
                || (ec_b = BN_new()) == NULL
                || (ec_gen = BN_new()) == NULL
                || (ec_order = BN_new()) == NULL
                || (ec_cofactor = BN_new()) == NULL) {
            perror("Can't allocate BN");
            goto end;
        }

        is_prime = (EC_METHOD_get_field_type(meth) == NID_X9_62_prime_field);
        if (!is_prime) {
            BIO_printf(bio_err, "Can only handle X9.62 prime fields\n");
            goto end;
        }

        if (!EC_GROUP_get_curve_GFp(group, ec_p, ec_a, ec_b, NULL))
            goto end;

        if ((point = EC_GROUP_get0_generator(group)) == NULL)
            goto end;
        if (!EC_POINT_point2bn(group, point,
                               EC_GROUP_get_point_conversion_form(group),
                               ec_gen, NULL))
            goto end;
        if (!EC_GROUP_get_order(group, ec_order, NULL))
            goto end;
        if (!EC_GROUP_get_cofactor(group, ec_cofactor, NULL))
            goto end;

        if (!ec_p || !ec_a || !ec_b || !ec_gen || !ec_order || !ec_cofactor)
            goto end;

        len = BN_num_bits(ec_order);

        if ((tmp_len = (size_t)BN_num_bytes(ec_p)) > buf_len)
            buf_len = tmp_len;
        if ((tmp_len = (size_t)BN_num_bytes(ec_a)) > buf_len)
            buf_len = tmp_len;
        if ((tmp_len = (size_t)BN_num_bytes(ec_b)) > buf_len)
            buf_len = tmp_len;
        if ((tmp_len = (size_t)BN_num_bytes(ec_gen)) > buf_len)
            buf_len = tmp_len;
        if ((tmp_len = (size_t)BN_num_bytes(ec_order)) > buf_len)
            buf_len = tmp_len;
        if ((tmp_len = (size_t)BN_num_bytes(ec_cofactor)) > buf_len)
            buf_len = tmp_len;

        buffer = app_malloc(buf_len, "BN buffer");

        BIO_printf(out, "EC_GROUP *get_ec_group_%d(void)\n{\n", len);
        print_bignum_var(out, ec_p, "ec_p", len, buffer);
        print_bignum_var(out, ec_a, "ec_a", len, buffer);
        print_bignum_var(out, ec_b, "ec_b", len, buffer);
        print_bignum_var(out, ec_gen, "ec_gen", len, buffer);
        print_bignum_var(out, ec_order, "ec_order", len, buffer);
        print_bignum_var(out, ec_cofactor, "ec_cofactor", len, buffer);
        BIO_printf(out, "    int ok = 0;\n"
                        "    EC_GROUP *group = NULL;\n"
                        "    EC_POINT *point = NULL;\n"
                        "    BIGNUM *tmp_1 = NULL;\n"
                        "    BIGNUM *tmp_2 = NULL;\n"
                        "    BIGNUM *tmp_3 = NULL;\n"
                        "\n");

        BIO_printf(out, "    if ((tmp_1 = BN_bin2bn(ec_p_%d, sizeof (ec_p_%d), NULL)) == NULL)\n"
                        "        goto err;\n", len, len);
        BIO_printf(out, "    if ((tmp_2 = BN_bin2bn(ec_a_%d, sizeof (ec_a_%d), NULL)) == NULL)\n"
                        "        goto err;\n", len, len);
        BIO_printf(out, "    if ((tmp_3 = BN_bin2bn(ec_b_%d, sizeof (ec_b_%d), NULL)) == NULL)\n"
                        "        goto err;\n", len, len);
        BIO_printf(out, "    if ((group = EC_GROUP_new_curve_GFp(tmp_1, tmp_2, tmp_3, NULL)) == NULL)\n"
                        "        goto err;\n"
                        "\n");
        BIO_printf(out, "    /* build generator */\n");
        BIO_printf(out, "    if ((tmp_1 = BN_bin2bn(ec_gen_%d, sizeof (ec_gen_%d), tmp_1)) == NULL)\n"
                        "        goto err;\n", len, len);
        BIO_printf(out, "    point = EC_POINT_bn2point(group, tmp_1, NULL, NULL);\n");
        BIO_printf(out, "    if (point == NULL)\n"
                        "        goto err;\n");
        BIO_printf(out, "    if ((tmp_2 = BN_bin2bn(ec_order_%d, sizeof (ec_order_%d), tmp_2)) == NULL)\n"
                        "        goto err;\n", len, len);
        BIO_printf(out, "    if ((tmp_3 = BN_bin2bn(ec_cofactor_%d, sizeof (ec_cofactor_%d), tmp_3)) == NULL)\n"
                        "        goto err;\n", len, len);
        BIO_printf(out, "    if (!EC_GROUP_set_generator(group, point, tmp_2, tmp_3))\n"
                        "        goto err;\n"
                        "ok = 1;"
                        "\n");
        BIO_printf(out, "err:\n"
                        "    BN_free(tmp_1);\n"
                        "    BN_free(tmp_2);\n"
                        "    BN_free(tmp_3);\n"
                        "    EC_POINT_free(point);\n"
                        "    if (!ok) {\n"
                        "        EC_GROUP_free(group);\n"
                        "        return NULL;\n"
                        "    }\n"
                        "    return (group);\n"
                        "}\n");
    }

    if (!noout) {
        if (outformat == FORMAT_ASN1)
            i = i2d_ECPKParameters_bio(out, group);
        else
            i = PEM_write_bio_ECPKParameters(out, group);
        if (!i) {
            BIO_printf(bio_err, "unable to write elliptic "
                       "curve parameters\n");
            ERR_print_errors(bio_err);
            goto end;
        }
    }

    if (need_rand) {
        app_RAND_load_file(NULL, (inrand != NULL));
        if (inrand != NULL)
            BIO_printf(bio_err, "%ld semi-random bytes loaded\n",
                       app_RAND_load_files(inrand));
    }

    if (genkey) {
        EC_KEY *eckey = EC_KEY_new();

        if (eckey == NULL)
            goto end;

        assert(need_rand);

        if (EC_KEY_set_group(eckey, group) == 0)
            goto end;

        if (!EC_KEY_generate_key(eckey)) {
            EC_KEY_free(eckey);
            goto end;
        }
        if (outformat == FORMAT_ASN1)
            i = i2d_ECPrivateKey_bio(out, eckey);
        else
            i = PEM_write_bio_ECPrivateKey(out, eckey, NULL,
                                           NULL, 0, NULL, NULL);
        EC_KEY_free(eckey);
    }

    if (need_rand)
        app_RAND_write_file(NULL);

    ret = 0;
 end:
    BN_free(ec_p);
    BN_free(ec_a);
    BN_free(ec_b);
    BN_free(ec_gen);
    BN_free(ec_order);
    BN_free(ec_cofactor);
    OPENSSL_free(buffer);
    BIO_free(in);
    BIO_free_all(out);
    EC_GROUP_free(group);
    return (ret);
}
コード例 #13
0
static void timings(EC_GROUP *group, int type, BN_CTX *ctx)
	{
	clock_t clck;
	int i, j;
	BIGNUM *s;
	BIGNUM *r[10], *r0[10];
	EC_POINT *P;
		
	s = BN_new();
	if (s == NULL) ABORT;

	fprintf(stdout, "Timings for %d-bit field, ", EC_GROUP_get_degree(group));
	if (!EC_GROUP_get_order(group, s, ctx)) ABORT;
	fprintf(stdout, "%d-bit scalars ", (int)BN_num_bits(s));
	fflush(stdout);

	P = EC_POINT_new(group);
	if (P == NULL) ABORT;
	EC_POINT_copy(P, EC_GROUP_get0_generator(group));

	for (i = 0; i < 10; i++)
		{
		if ((r[i] = BN_new()) == NULL) ABORT;
		if (!BN_pseudo_rand(r[i], BN_num_bits(s), 0, 0)) ABORT;
		if (type != TIMING_BASE_PT)
			{
			if ((r0[i] = BN_new()) == NULL) ABORT;
			if (!BN_pseudo_rand(r0[i], BN_num_bits(s), 0, 0)) ABORT;
			}
		}

	clck = clock();
	for (i = 0; i < 10; i++)
		{
		for (j = 0; j < 10; j++)
			{
			if (!EC_POINT_mul(group, P, (type != TIMING_RAND_PT) ? r[i] : NULL, 
				(type != TIMING_BASE_PT) ? P : NULL, (type != TIMING_BASE_PT) ? r0[i] : NULL, ctx)) ABORT;
			}
		}
	clck = clock() - clck;

	fprintf(stdout, "\n");

#ifdef CLOCKS_PER_SEC
	/* "To determine the time in seconds, the value returned
	 * by the clock function should be divided by the value
	 * of the macro CLOCKS_PER_SEC."
	 *                                       -- ISO/IEC 9899 */
#	define UNIT "s"
#else
	/* "`CLOCKS_PER_SEC' undeclared (first use this function)"
	 *                            -- cc on NeXTstep/OpenStep */
#	define UNIT "units"
#	define CLOCKS_PER_SEC 1
#endif

	if (type == TIMING_BASE_PT) {
		fprintf(stdout, "%i %s in %.2f " UNIT "\n", i*j,
			"base point multiplications", (double)clck/CLOCKS_PER_SEC);
	} else if (type == TIMING_RAND_PT) {
		fprintf(stdout, "%i %s in %.2f " UNIT "\n", i*j,
			"random point multiplications", (double)clck/CLOCKS_PER_SEC);
	} else if (type == TIMING_SIMUL) {
		fprintf(stdout, "%i %s in %.2f " UNIT "\n", i*j,
			"s*P+t*Q operations", (double)clck/CLOCKS_PER_SEC);
	}
	fprintf(stdout, "average: %.4f " UNIT "\n", (double)clck/(CLOCKS_PER_SEC*i*j));

	EC_POINT_free(P);
	BN_free(s);
	for (i = 0; i < 10; i++)
		{
		BN_free(r[i]);
		if (type != TIMING_BASE_PT) BN_free(r0[i]);
		}
	}
コード例 #14
0
ファイル: ectool.c プロジェクト: LiTianjue/GmSSL
int main(int argc, const char *argv[])
{
	int r;
	int ok = 0;
	char *prog = "ecc";

	
	// libpopt var
	poptContext popt_ctx;
	const char **rest;
	int command = 0;
	char *curve_name = "secp192k1";
	int point_compressed = 0;
	point_conversion_form_t point_form;

	struct poptOption options[] = {
		{"curve-name",		'c', POPT_ARG_STRING, &curve_name, 0,		"elliptic curve name", "NAME"},
		{"point-compressed",	'z', POPT_ARG_NONE, &point_compressed, 0,	"point format, compress or uncompress", NULL},
		{"print-curve",		'p', POPT_ARG_VAL, &command, ECC_PRINT,		"print elliptic curve parameters", NULL},
		{"random-private-key",	 0,  POPT_ARG_VAL, &command, ECC_RAND_SKEY,	"random generate a private key\n", NULL},
		{"random-keypair",	 0,  POPT_ARG_VAL, &command, ECC_RAND_KEYPAIR,	"generate a random key pair\n", NULL},
		{"check-point",		'e', POPT_ARG_VAL, &command, ECC_CHECK_POINT,	"check if point is valid\n", NULL},
		{"point-add",		'a', POPT_ARG_VAL, &command, ECC_ADD,		"elliptic curve point addition", NULL},
		{"point-double",	'b', POPT_ARG_VAL, &command, ECC_DOUBLE,	"elliptic curve point double", NULL},
		{"point-mul",		'x', POPT_ARG_VAL, &command, ECC_MUL,		"k*G", NULL},
		{"point-mul-generator",	'X', POPT_ARG_VAL, &command, ECC_MUL_G,		"elliptic curve point scalar multiply", NULL},
		{"point-invert",	'i', POPT_ARG_VAL, &command, ECC_INVERT,	"elliptic curve point inverse", NULL},
		{"ecdsa-sign",		's', POPT_ARG_VAL, &command, ECC_SIGN,		"ecdsa sign", NULL},
		{"ecdsa-verify",	'v', POPT_ARG_VAL, &command, ECC_VERIFY,	"ecdsa verify", NULL},
		POPT_AUTOHELP
		POPT_TABLEEND
	};

	// openssl var
	EC_GROUP *ec_group = NULL;
	EC_POINT *P = NULL;
	EC_POINT *Q = NULL;
	EC_POINT *R = NULL;
	BIGNUM *k = BN_new();
	BN_CTX *bn_ctx = BN_CTX_new();


	// argument parsing
	popt_ctx = poptGetContext(argv[0], argc, argv, options, 0);
	if ((r = poptGetNextOpt(popt_ctx)) < -1) {
		fprintf(stderr, "%s: bad argument %s: %s\n", argv[0], 
			poptBadOption(popt_ctx, POPT_BADOPTION_NOALIAS), 
			poptStrerror(r));
		goto exit;
	}
	rest = poptGetArgs(popt_ctx);


	// check arguments
	ec_group = EC_GROUP_new_by_curve_name(OBJ_txt2nid(curve_name));
	if (ec_group == NULL) {
		fprintf(stderr, "%s: unknown curve name\n", prog);
		goto exit;
	}

	P = EC_POINT_new(ec_group);
	Q = EC_POINT_new(ec_group);
	R = EC_POINT_new(ec_group);

	point_form = point_compressed ? POINT_CONVERSION_COMPRESSED : POINT_CONVERSION_UNCOMPRESSED;

	switch (command) {
	case ECC_PRINT:
		{
		BIGNUM *p = BN_new();
		BIGNUM *a = BN_new();
		BIGNUM *b = BN_new();
		char *generator;
		BIGNUM *order = BN_new();
		BIGNUM *cofactor = BN_new();

		EC_GROUP_get_curve_GFp(ec_group, p, a, b, bn_ctx);
		generator = EC_POINT_point2hex(ec_group, EC_GROUP_get0_generator(ec_group), point_form, bn_ctx);
		EC_GROUP_get_order(ec_group, order, bn_ctx);
		EC_GROUP_get_cofactor(ec_group, cofactor, bn_ctx);
		
		fprintf(stdout, "Name      : %s\n", OBJ_nid2sn(EC_GROUP_get_curve_name(ec_group)));
		fprintf(stdout, "FieldType : %s\n", "PrimeField");
		fprintf(stdout, "Prime     : %s\n", BN_bn2hex(p));
		fprintf(stdout, "A         : %s\n", BN_bn2hex(a));
		fprintf(stdout, "B         : %s\n", BN_bn2hex(b));
		fprintf(stdout, "Generator : %s\n", generator);
		fprintf(stdout, "Order     : %s\n", BN_bn2hex(order));
		fprintf(stdout, "Cofactor  : %s\n", BN_bn2hex(cofactor));

		BN_free(p);
		BN_free(a);
		BN_free(b);
		BN_free(order);
		BN_free(cofactor);

		break;
		}
	case ECC_CHECK_POINT:
		{
		if (!rest) {
			fprintf(stderr, "%s: short of point\n", prog);
			goto exit;
		}
		if (!rest[0]) {
			fprintf(stderr, "%s: short of point\n", prog);
			goto exit;
		}
		if (EC_POINT_hex2point(ec_group, rest[0], P, bn_ctx))
			fprintf(stdout, "ture\n");
		else
			fprintf(stdout, "false\n");
		break;
		}
	case ECC_RAND_SKEY:
		{
		EC_KEY *ec_key = EC_KEY_new();
		EC_KEY_set_group(ec_key, ec_group);
		EC_KEY_generate_key(ec_key);
		fprintf(stdout, "%s\n", BN_bn2hex(EC_KEY_get0_private_key(ec_key)));
		EC_KEY_free(ec_key);
		break;
		}
	case ECC_RAND_KEYPAIR:
		{
		EC_KEY *ec_key = EC_KEY_new();
		EC_KEY_set_group(ec_key, ec_group);
		EC_KEY_generate_key(ec_key);
		fprintf(stdout, "%s\n", BN_bn2hex(EC_KEY_get0_private_key(ec_key)));
		fprintf(stdout, "%s\n", EC_POINT_point2hex(ec_group, EC_KEY_get0_public_key(ec_key), point_form, bn_ctx));
		EC_KEY_free(ec_key);
		break;
		}
	case ECC_ADD:
		{
		if (!rest) {
			fprintf(stderr, "%s: short of point\n", prog);
			goto exit;
		}
		if (!rest[0] || !rest[1]) {
			fprintf(stderr, "%s: short of point\n", prog);
			goto exit;
		}			
		if (!EC_POINT_hex2point(ec_group, rest[1], P, bn_ctx)) {
			fprintf(stderr, "%s: first point invalid\n", prog);
			goto exit;
		}
		if (!EC_POINT_hex2point(ec_group, rest[1], Q, bn_ctx)) {
			fprintf(stderr, "%s: second point invalid\n", prog);
			goto exit;
		}
		EC_POINT_add(ec_group, R, P, Q, bn_ctx);
		fprintf(stdout, "%s\n", EC_POINT_point2hex(ec_group, R, point_form, bn_ctx));
		break;
		}
	case ECC_DOUBLE:
		{
		EC_POINT_dbl(ec_group, R, P, bn_ctx);
		fprintf(stdout, "%s\n", EC_POINT_point2hex(ec_group, R, point_form, bn_ctx));
		break;
		}
	case ECC_MUL:
		{
		BIGNUM *order = NULL;

		if (!BN_hex2bn(&k, rest[0])) {
			fprintf(stderr, "%s: integer invalid\n", prog);
			goto exit;
		}
		
		order = BN_new();
		EC_GROUP_get_order(ec_group, order, bn_ctx);
		if (BN_cmp(k, order) >= 0) {
			fprintf(stderr, "%s: integer value invalid\n", prog);
			BN_free(order);
			goto exit;
		}
		BN_free(order);

		if (!EC_POINT_hex2point(ec_group, rest[1], P, bn_ctx)) {
			fprintf(stderr, "%s: point invalid\n", prog);
			goto exit;
		}

		EC_POINT_mul(ec_group, R, k, P, NULL, bn_ctx);
		fprintf(stdout, "%s\n", EC_POINT_point2hex(ec_group, R, point_form, bn_ctx));

		break;
		}
	case ECC_MUL_G:
		{
		BIGNUM *order = NULL;
		if (!BN_hex2bn(&k, rest[0])) {
			fprintf(stderr, "%s: integer format invalid\n", prog);
			goto exit;
		}
		
		order = BN_new();
		EC_GROUP_get_order(ec_group, order, bn_ctx);
		if (BN_cmp(k, order) >= 0) {
			fprintf(stderr, "%s: integer value invalid\n", prog);
			BN_free(order);
			goto exit;
		}
		BN_free(order);
		
		EC_POINT_mul(ec_group, R, k, EC_GROUP_get0_generator(ec_group), NULL, bn_ctx);
		fprintf(stdout, "%s\n", EC_POINT_point2hex(ec_group, R, point_form, bn_ctx));
		break;
		}
	default:
		fprintf(stderr, "%s: command is required\n", prog);
		break;
	}
	ok = 1;

exit:
	if (ec_group) EC_GROUP_free(ec_group);
	if (P) EC_POINT_free(P);
	if (k) BN_free(k);
	if (bn_ctx) BN_CTX_free(bn_ctx);

	return ok ? 0 : -1;
}
コード例 #15
0
ファイル: ringsig.cpp プロジェクト: kewde/shadowproject
int initialiseRingSigs()
{
    if (fDebugRingSig)
        LogPrintf("initialiseRingSigs()\n");

    if (!(ecGrp = EC_GROUP_new_by_curve_name(NID_secp256k1)))
        return errorN(1, "initialiseRingSigs(): EC_GROUP_new_by_curve_name failed.");

    if (!(bnCtx = BN_CTX_new()))
        return errorN(1, "initialiseRingSigs(): BN_CTX_new failed.");

    BN_CTX_start(bnCtx);

    //Create a new EC group for the keyImage with all of the characteristics of ecGrp.
    if(!(ecGrpKi = EC_GROUP_dup(ecGrp))){
	return errorN(1, "initialiseRingSigs(): EC_GROUP_dup failed.");
    }

    // get order and cofactor
    bnOrder = BN_new();
    if(!EC_GROUP_get_order(ecGrp, bnOrder, bnCtx)){
        return errorN(1, "initialiseRingSigs(): EC_GROUP_get_order failed.");
    }

    BIGNUM *bnCofactor = BN_CTX_get(bnCtx);
    if(!EC_GROUP_get_cofactor(ecGrp, bnCofactor, bnCtx)){
    	return errorN(1, "initialiseRingSigs(): EC_GROUP_get_cofactor failed.");
    }

    // get the original generator
    EC_POINT *ptBase = const_cast<EC_POINT*>(EC_GROUP_get0_generator(ecGrp)); //PS: never clear this point

    // create key image basepoint variable
    EC_POINT *ptBaseKi = EC_POINT_new(ecGrpKi);
    BIGNUM *bnBaseKi = BN_CTX_get(bnCtx);

    // get original basepoint in BIG NUMS.
    EC_POINT_point2bn(ecGrp, ptBase, POINT_CONVERSION_COMPRESSED, bnBaseKi, bnCtx);

    //create "1" in BIG NUMS
    BIGNUM *bnBaseKiAdd = BN_CTX_get(bnCtx);
    std::string num_str = "1";
    BN_dec2bn(&bnBaseKiAdd, num_str.c_str());

    // add 1 to original base point and store in key image basepoint (BIG NUMS)
    BN_add(bnBaseKi, bnBaseKi, bnBaseKiAdd);

    // key image basepoint from bignum to point in ptBaseKi
    if(!EC_POINT_bn2point(ecGrp, bnBaseKi, ptBaseKi, bnCtx))
       return errorN(1, "initialiseRingSigs(): EC_POINT_bn2point failed.");

    // set generator of ecGrpKi
    if(!EC_GROUP_set_generator(ecGrpKi, ptBaseKi, bnOrder, bnCofactor)){
	 return errorN(1, "initialiseRingSigs(): EC_GROUP_set_generator failed.");
    }

    if (fDebugRingSig)
    {
        // Debugging...
        const EC_POINT *generator = EC_GROUP_get0_generator(ecGrp);
        const EC_POINT *generatorKi = EC_GROUP_get0_generator(ecGrpKi);
        char *genPoint = EC_POINT_point2hex(ecGrp, generator, POINT_CONVERSION_UNCOMPRESSED, bnCtx);
        char *genPointKi = EC_POINT_point2hex(ecGrpKi, generatorKi, POINT_CONVERSION_UNCOMPRESSED, bnCtx);

        LogPrintf("generator ecGrp:   %s\ngenerator ecGrpKi: %s\n", genPoint, genPointKi);
    }

    EC_POINT_free(ptBaseKi);
    BN_CTX_end(bnCtx);
    return 0;
};
コード例 #16
0
ファイル: ectest.c プロジェクト: xyzy/mips-openssl_0.9.7
static void timings(EC_GROUP *group, int multi, BN_CTX *ctx)
	{
	clock_t clck;
	int i, j;
	BIGNUM *s, *s0;
	EC_POINT *P;
		
	s = BN_new();
	s0 = BN_new();
	if (s == NULL || s0 == NULL) ABORT;

	if (!EC_GROUP_get_curve_GFp(group, s, NULL, NULL, ctx)) ABORT;
	fprintf(stdout, "Timings for %d bit prime, ", (int)BN_num_bits(s));
	if (!EC_GROUP_get_order(group, s, ctx)) ABORT;
	fprintf(stdout, "%d bit scalars ", (int)BN_num_bits(s));
	fflush(stdout);

	P = EC_POINT_new(group);
	if (P == NULL) ABORT;
	EC_POINT_copy(P, EC_GROUP_get0_generator(group));

	clck = clock();
	for (i = 0; i < 10; i++)
		{
		if (!BN_pseudo_rand(s, BN_num_bits(s), 0, 0)) ABORT;
		if (multi)
			{
			if (!BN_pseudo_rand(s0, BN_num_bits(s), 0, 0)) ABORT;
			}
		for (j = 0; j < 10; j++)
			{
			if (!EC_POINT_mul(group, P, s, multi ? P : NULL, multi ? s0 : NULL, ctx)) ABORT;
			}
		fprintf(stdout, ".");
		fflush(stdout);
		}
	fprintf(stdout, "\n");
	
	clck = clock() - clck;

#ifdef CLOCKS_PER_SEC
	/* "To determine the time in seconds, the value returned
	 * by the clock function should be divided by the value
	 * of the macro CLOCKS_PER_SEC."
	 *                                       -- ISO/IEC 9899 */
#	define UNIT "s"
#else
	/* "`CLOCKS_PER_SEC' undeclared (first use this function)"
	 *                            -- cc on NeXTstep/OpenStep */
#	define UNIT "units"
#	define CLOCKS_PER_SEC 1
#endif

	fprintf(stdout, "%i %s in %.2f " UNIT "\n", i*j,
		multi ? "s*P+t*Q operations" : "point multiplications",
		(double)clck/CLOCKS_PER_SEC);
	fprintf(stdout, "average: %.4f " UNIT "\n", (double)clck/(CLOCKS_PER_SEC*i*j));

	EC_POINT_free(P);
	BN_free(s);
	BN_free(s0);
	}
コード例 #17
0
ファイル: ecparam.c プロジェクト: benwh4/libressl
int 
ecparam_main(int argc, char **argv)
{
	EC_GROUP *group = NULL;
	point_conversion_form_t form = POINT_CONVERSION_UNCOMPRESSED;
	int new_form = 0;
	int asn1_flag = OPENSSL_EC_NAMED_CURVE;
	int new_asn1_flag = 0;
	char *curve_name = NULL, *inrand = NULL;
	int list_curves = 0, no_seed = 0, check = 0, badops = 0, text = 0,
	 i, genkey = 0;
	char *infile = NULL, *outfile = NULL, *prog;
	BIO *in = NULL, *out = NULL;
	int informat, outformat, noout = 0, C = 0, ret = 1;
	char *engine = NULL;

	BIGNUM *ec_p = NULL, *ec_a = NULL, *ec_b = NULL, *ec_gen = NULL,
	*ec_order = NULL, *ec_cofactor = NULL;
	unsigned char *buffer = NULL;

	if (!load_config(bio_err, NULL))
		goto end;

	informat = FORMAT_PEM;
	outformat = FORMAT_PEM;

	prog = argv[0];
	argc--;
	argv++;
	while (argc >= 1) {
		if (strcmp(*argv, "-inform") == 0) {
			if (--argc < 1)
				goto bad;
			informat = str2fmt(*(++argv));
		} else if (strcmp(*argv, "-outform") == 0) {
			if (--argc < 1)
				goto bad;
			outformat = str2fmt(*(++argv));
		} else if (strcmp(*argv, "-in") == 0) {
			if (--argc < 1)
				goto bad;
			infile = *(++argv);
		} else if (strcmp(*argv, "-out") == 0) {
			if (--argc < 1)
				goto bad;
			outfile = *(++argv);
		} else if (strcmp(*argv, "-text") == 0)
			text = 1;
		else if (strcmp(*argv, "-C") == 0)
			C = 1;
		else if (strcmp(*argv, "-check") == 0)
			check = 1;
		else if (strcmp(*argv, "-name") == 0) {
			if (--argc < 1)
				goto bad;
			curve_name = *(++argv);
		} else if (strcmp(*argv, "-list_curves") == 0)
			list_curves = 1;
		else if (strcmp(*argv, "-conv_form") == 0) {
			if (--argc < 1)
				goto bad;
			++argv;
			new_form = 1;
			if (strcmp(*argv, "compressed") == 0)
				form = POINT_CONVERSION_COMPRESSED;
			else if (strcmp(*argv, "uncompressed") == 0)
				form = POINT_CONVERSION_UNCOMPRESSED;
			else if (strcmp(*argv, "hybrid") == 0)
				form = POINT_CONVERSION_HYBRID;
			else
				goto bad;
		} else if (strcmp(*argv, "-param_enc") == 0) {
			if (--argc < 1)
				goto bad;
			++argv;
			new_asn1_flag = 1;
			if (strcmp(*argv, "named_curve") == 0)
				asn1_flag = OPENSSL_EC_NAMED_CURVE;
			else if (strcmp(*argv, "explicit") == 0)
				asn1_flag = 0;
			else
				goto bad;
		} else if (strcmp(*argv, "-no_seed") == 0)
			no_seed = 1;
		else if (strcmp(*argv, "-noout") == 0)
			noout = 1;
		else if (strcmp(*argv, "-genkey") == 0) {
			genkey = 1;
		} else if (strcmp(*argv, "-rand") == 0) {
			if (--argc < 1)
				goto bad;
			inrand = *(++argv);
		} else if (strcmp(*argv, "-engine") == 0) {
			if (--argc < 1)
				goto bad;
			engine = *(++argv);
		} else {
			BIO_printf(bio_err, "unknown option %s\n", *argv);
			badops = 1;
			break;
		}
		argc--;
		argv++;
	}

	if (badops) {
bad:
		BIO_printf(bio_err, "%s [options] <infile >outfile\n", prog);
		BIO_printf(bio_err, "where options are\n");
		BIO_printf(bio_err, " -inform arg       input format - "
		    "default PEM (DER or PEM)\n");
		BIO_printf(bio_err, " -outform arg      output format - "
		    "default PEM\n");
		BIO_printf(bio_err, " -in  arg          input file  - "
		    "default stdin\n");
		BIO_printf(bio_err, " -out arg          output file - "
		    "default stdout\n");
		BIO_printf(bio_err, " -noout            do not print the "
		    "ec parameter\n");
		BIO_printf(bio_err, " -text             print the ec "
		    "parameters in text form\n");
		BIO_printf(bio_err, " -check            validate the ec "
		    "parameters\n");
		BIO_printf(bio_err, " -C                print a 'C' "
		    "function creating the parameters\n");
		BIO_printf(bio_err, " -name arg         use the "
		    "ec parameters with 'short name' name\n");
		BIO_printf(bio_err, " -list_curves      prints a list of "
		    "all currently available curve 'short names'\n");
		BIO_printf(bio_err, " -conv_form arg    specifies the "
		    "point conversion form \n");
		BIO_printf(bio_err, "                   possible values:"
		    " compressed\n");
		BIO_printf(bio_err, "                                   "
		    " uncompressed (default)\n");
		BIO_printf(bio_err, "                                   "
		    " hybrid\n");
		BIO_printf(bio_err, " -param_enc arg    specifies the way"
		    " the ec parameters are encoded\n");
		BIO_printf(bio_err, "                   in the asn1 der "
		    "encoding\n");
		BIO_printf(bio_err, "                   possible values:"
		    " named_curve (default)\n");
		BIO_printf(bio_err, "                                   "
		    " explicit\n");
		BIO_printf(bio_err, " -no_seed          if 'explicit'"
		    " parameters are chosen do not"
		    " use the seed\n");
		BIO_printf(bio_err, " -genkey           generate ec"
		    " key\n");
		BIO_printf(bio_err, " -rand file        files to use for"
		    " random number input\n");
		BIO_printf(bio_err, " -engine e         use engine e, "
		    "possibly a hardware device\n");
		goto end;
	}
	ERR_load_crypto_strings();

	in = BIO_new(BIO_s_file());
	out = BIO_new(BIO_s_file());
	if ((in == NULL) || (out == NULL)) {
		ERR_print_errors(bio_err);
		goto end;
	}
	if (infile == NULL)
		BIO_set_fp(in, stdin, BIO_NOCLOSE);
	else {
		if (BIO_read_filename(in, infile) <= 0) {
			perror(infile);
			goto end;
		}
	}
	if (outfile == NULL) {
		BIO_set_fp(out, stdout, BIO_NOCLOSE);
	} else {
		if (BIO_write_filename(out, outfile) <= 0) {
			perror(outfile);
			goto end;
		}
	}

#ifndef OPENSSL_NO_ENGINE
	setup_engine(bio_err, engine, 0);
#endif

	if (list_curves) {
		EC_builtin_curve *curves = NULL;
		size_t crv_len = 0;
		size_t n = 0;

		crv_len = EC_get_builtin_curves(NULL, 0);

		curves = reallocarray(NULL, crv_len, sizeof(EC_builtin_curve));

		if (curves == NULL)
			goto end;

		if (!EC_get_builtin_curves(curves, crv_len)) {
			free(curves);
			goto end;
		}
		for (n = 0; n < crv_len; n++) {
			const char *comment;
			const char *sname;
			comment = curves[n].comment;
			sname = OBJ_nid2sn(curves[n].nid);
			if (comment == NULL)
				comment = "CURVE DESCRIPTION NOT AVAILABLE";
			if (sname == NULL)
				sname = "";

			BIO_printf(out, "  %-10s: ", sname);
			BIO_printf(out, "%s\n", comment);
		}

		free(curves);
		ret = 0;
		goto end;
	}
	if (curve_name != NULL) {
		int nid;

		/*
		 * workaround for the SECG curve names secp192r1 and
		 * secp256r1 (which are the same as the curves prime192v1 and
		 * prime256v1 defined in X9.62)
		 */
		if (!strcmp(curve_name, "secp192r1")) {
			BIO_printf(bio_err, "using curve name prime192v1 "
			    "instead of secp192r1\n");
			nid = NID_X9_62_prime192v1;
		} else if (!strcmp(curve_name, "secp256r1")) {
			BIO_printf(bio_err, "using curve name prime256v1 "
			    "instead of secp256r1\n");
			nid = NID_X9_62_prime256v1;
		} else
			nid = OBJ_sn2nid(curve_name);

		if (nid == 0) {
			BIO_printf(bio_err, "unknown curve name (%s)\n",
			    curve_name);
			goto end;
		}
		group = EC_GROUP_new_by_curve_name(nid);
		if (group == NULL) {
			BIO_printf(bio_err, "unable to create curve (%s)\n",
			    curve_name);
			goto end;
		}
		EC_GROUP_set_asn1_flag(group, asn1_flag);
		EC_GROUP_set_point_conversion_form(group, form);
	} else if (informat == FORMAT_ASN1) {
		group = d2i_ECPKParameters_bio(in, NULL);
	} else if (informat == FORMAT_PEM) {
		group = PEM_read_bio_ECPKParameters(in, NULL, NULL, NULL);
	} else {
		BIO_printf(bio_err, "bad input format specified\n");
		goto end;
	}

	if (group == NULL) {
		BIO_printf(bio_err,
		    "unable to load elliptic curve parameters\n");
		ERR_print_errors(bio_err);
		goto end;
	}
	if (new_form)
		EC_GROUP_set_point_conversion_form(group, form);

	if (new_asn1_flag)
		EC_GROUP_set_asn1_flag(group, asn1_flag);

	if (no_seed) {
		EC_GROUP_set_seed(group, NULL, 0);
	}
	if (text) {
		if (!ECPKParameters_print(out, group, 0))
			goto end;
	}
	if (check) {
		if (group == NULL)
			BIO_printf(bio_err, "no elliptic curve parameters\n");
		BIO_printf(bio_err, "checking elliptic curve parameters: ");
		if (!EC_GROUP_check(group, NULL)) {
			BIO_printf(bio_err, "failed\n");
			ERR_print_errors(bio_err);
		} else
			BIO_printf(bio_err, "ok\n");

	}
	if (C) {
		size_t buf_len = 0, tmp_len = 0;
		const EC_POINT *point;
		int is_prime, len = 0;
		const EC_METHOD *meth = EC_GROUP_method_of(group);

		if ((ec_p = BN_new()) == NULL || (ec_a = BN_new()) == NULL ||
		    (ec_b = BN_new()) == NULL || (ec_gen = BN_new()) == NULL ||
		    (ec_order = BN_new()) == NULL ||
		    (ec_cofactor = BN_new()) == NULL) {
			perror("malloc");
			goto end;
		}
		is_prime = (EC_METHOD_get_field_type(meth) ==
		    NID_X9_62_prime_field);

		if (is_prime) {
			if (!EC_GROUP_get_curve_GFp(group, ec_p, ec_a,
				ec_b, NULL))
				goto end;
		} else {
			/* TODO */
			goto end;
		}

		if ((point = EC_GROUP_get0_generator(group)) == NULL)
			goto end;
		if (!EC_POINT_point2bn(group, point,
			EC_GROUP_get_point_conversion_form(group), ec_gen,
			NULL))
			goto end;
		if (!EC_GROUP_get_order(group, ec_order, NULL))
			goto end;
		if (!EC_GROUP_get_cofactor(group, ec_cofactor, NULL))
			goto end;

		if (!ec_p || !ec_a || !ec_b || !ec_gen ||
		    !ec_order || !ec_cofactor)
			goto end;

		len = BN_num_bits(ec_order);

		if ((tmp_len = (size_t) BN_num_bytes(ec_p)) > buf_len)
			buf_len = tmp_len;
		if ((tmp_len = (size_t) BN_num_bytes(ec_a)) > buf_len)
			buf_len = tmp_len;
		if ((tmp_len = (size_t) BN_num_bytes(ec_b)) > buf_len)
			buf_len = tmp_len;
		if ((tmp_len = (size_t) BN_num_bytes(ec_gen)) > buf_len)
			buf_len = tmp_len;
		if ((tmp_len = (size_t) BN_num_bytes(ec_order)) > buf_len)
			buf_len = tmp_len;
		if ((tmp_len = (size_t) BN_num_bytes(ec_cofactor)) > buf_len)
			buf_len = tmp_len;

		buffer = (unsigned char *) malloc(buf_len);

		if (buffer == NULL) {
			perror("malloc");
			goto end;
		}
		ecparam_print_var(out, ec_p, "ec_p", len, buffer);
		ecparam_print_var(out, ec_a, "ec_a", len, buffer);
		ecparam_print_var(out, ec_b, "ec_b", len, buffer);
		ecparam_print_var(out, ec_gen, "ec_gen", len, buffer);
		ecparam_print_var(out, ec_order, "ec_order", len, buffer);
		ecparam_print_var(out, ec_cofactor, "ec_cofactor", len,
		    buffer);

		BIO_printf(out, "\n\n");

		BIO_printf(out, "EC_GROUP *get_ec_group_%d(void)\n\t{\n", len);
		BIO_printf(out, "\tint ok=0;\n");
		BIO_printf(out, "\tEC_GROUP *group = NULL;\n");
		BIO_printf(out, "\tEC_POINT *point = NULL;\n");
		BIO_printf(out, "\tBIGNUM   *tmp_1 = NULL, *tmp_2 = NULL, "
		    "*tmp_3 = NULL;\n\n");
		BIO_printf(out, "\tif ((tmp_1 = BN_bin2bn(ec_p_%d, "
		    "sizeof(ec_p_%d), NULL)) == NULL)\n\t\t"
		    "goto err;\n", len, len);
		BIO_printf(out, "\tif ((tmp_2 = BN_bin2bn(ec_a_%d, "
		    "sizeof(ec_a_%d), NULL)) == NULL)\n\t\t"
		    "goto err;\n", len, len);
		BIO_printf(out, "\tif ((tmp_3 = BN_bin2bn(ec_b_%d, "
		    "sizeof(ec_b_%d), NULL)) == NULL)\n\t\t"
		    "goto err;\n", len, len);
		if (is_prime) {
			BIO_printf(out, "\tif ((group = EC_GROUP_new_curve_"
			    "GFp(tmp_1, tmp_2, tmp_3, NULL)) == NULL)"
			    "\n\t\tgoto err;\n\n");
		} else {
			/* TODO */
			goto end;
		}
		BIO_printf(out, "\t/* build generator */\n");
		BIO_printf(out, "\tif ((tmp_1 = BN_bin2bn(ec_gen_%d, "
		    "sizeof(ec_gen_%d), tmp_1)) == NULL)"
		    "\n\t\tgoto err;\n", len, len);
		BIO_printf(out, "\tpoint = EC_POINT_bn2point(group, tmp_1, "
		    "NULL, NULL);\n");
		BIO_printf(out, "\tif (point == NULL)\n\t\tgoto err;\n");
		BIO_printf(out, "\tif ((tmp_2 = BN_bin2bn(ec_order_%d, "
		    "sizeof(ec_order_%d), tmp_2)) == NULL)"
		    "\n\t\tgoto err;\n", len, len);
		BIO_printf(out, "\tif ((tmp_3 = BN_bin2bn(ec_cofactor_%d, "
		    "sizeof(ec_cofactor_%d), tmp_3)) == NULL)"
		    "\n\t\tgoto err;\n", len, len);
		BIO_printf(out, "\tif (!EC_GROUP_set_generator(group, point,"
		    " tmp_2, tmp_3))\n\t\tgoto err;\n");
		BIO_printf(out, "\n\tok=1;\n");
		BIO_printf(out, "err:\n");
		BIO_printf(out, "\tif (tmp_1)\n\t\tBN_free(tmp_1);\n");
		BIO_printf(out, "\tif (tmp_2)\n\t\tBN_free(tmp_2);\n");
		BIO_printf(out, "\tif (tmp_3)\n\t\tBN_free(tmp_3);\n");
		BIO_printf(out, "\tif (point)\n\t\tEC_POINT_free(point);\n");
		BIO_printf(out, "\tif (!ok)\n");
		BIO_printf(out, "\t\t{\n");
		BIO_printf(out, "\t\tEC_GROUP_free(group);\n");
		BIO_printf(out, "\t\tgroup = NULL;\n");
		BIO_printf(out, "\t\t}\n");
		BIO_printf(out, "\treturn(group);\n\t}\n");
	}
	if (!noout) {
		if (outformat == FORMAT_ASN1)
			i = i2d_ECPKParameters_bio(out, group);
		else if (outformat == FORMAT_PEM)
			i = PEM_write_bio_ECPKParameters(out, group);
		else {
			BIO_printf(bio_err, "bad output format specified for"
			    " outfile\n");
			goto end;
		}
		if (!i) {
			BIO_printf(bio_err, "unable to write elliptic "
			    "curve parameters\n");
			ERR_print_errors(bio_err);
			goto end;
		}
	}
	if (genkey) {
		EC_KEY *eckey = EC_KEY_new();

		if (eckey == NULL)
			goto end;

		if (EC_KEY_set_group(eckey, group) == 0)
			goto end;

		if (!EC_KEY_generate_key(eckey)) {
			EC_KEY_free(eckey);
			goto end;
		}
		if (outformat == FORMAT_ASN1)
			i = i2d_ECPrivateKey_bio(out, eckey);
		else if (outformat == FORMAT_PEM)
			i = PEM_write_bio_ECPrivateKey(out, eckey, NULL,
			    NULL, 0, NULL, NULL);
		else {
			BIO_printf(bio_err, "bad output format specified "
			    "for outfile\n");
			EC_KEY_free(eckey);
			goto end;
		}
		EC_KEY_free(eckey);
	}
	ret = 0;
end:
	if (ec_p)
		BN_free(ec_p);
	if (ec_a)
		BN_free(ec_a);
	if (ec_b)
		BN_free(ec_b);
	if (ec_gen)
		BN_free(ec_gen);
	if (ec_order)
		BN_free(ec_order);
	if (ec_cofactor)
		BN_free(ec_cofactor);
	free(buffer);
	if (in != NULL)
		BIO_free(in);
	if (out != NULL)
		BIO_free_all(out);
	if (group != NULL)
		EC_GROUP_free(group);
	
	return (ret);
}
コード例 #18
0
ファイル: bfibe_lib.c プロジェクト: winstard/GmSSL
int BFIBE_setup(const EC_GROUP *group, const EVP_MD *md,
	BFPublicParameters **pmpk, BFMasterSecret **pmsk)
{
	int ret = 0;
	BFPublicParameters *mpk = NULL;
	BFMasterSecret *msk = NULL;
	BN_CTX *bn_ctx = NULL;
	EC_POINT *point = NULL;
	BIGNUM *a;
	BIGNUM *b;

	if (!group || !pmpk || !pmsk) {
		BFIBEerr(BFIBE_F_BFIBE_SETUP, ERR_R_PASSED_NULL_PARAMETER);
		return 0;
	}

	if (!(bn_ctx = BN_CTX_new())) {
		BFIBEerr(BFIBE_F_BFIBE_SETUP, ERR_R_MALLOC_FAILURE);
		goto end;
	}

	BN_CTX_start(bn_ctx);
	a = BN_CTX_get(bn_ctx);
	b = BN_CTX_get(bn_ctx);
	if (!b) {
		BFIBEerr(BFIBE_F_BFIBE_SETUP, ERR_R_MALLOC_FAILURE);
		goto end;
	}

	mpk = BFPublicParameters_new();
	msk = BFMasterSecret_new();
	point = EC_POINT_new(group);

	if (!mpk || !msk || !point) {
		BFIBEerr(BFIBE_F_BFIBE_SETUP, ERR_R_MALLOC_FAILURE);
		goto end;
	}

	/*
	 * set mpk->version
	 * set mpk->curve
	 */

	mpk->version = BFIBE_VERSION;

	OPENSSL_assert(mpk->curve);
	ASN1_OBJECT_free(mpk->curve);
	if (!(mpk->curve = OBJ_nid2obj(NID_type1curve))) {
		BFIBEerr(BFIBE_F_BFIBE_SETUP, BFIBE_R_NOT_NAMED_CURVE);
		goto end;
	}

	/* mpk->p = group->p */
	if (!EC_GROUP_get_curve_GFp(group, mpk->p, a, b, bn_ctx)) {
		BFIBEerr(BFIBE_F_BFIBE_SETUP, ERR_R_EC_LIB);
		goto end;
	}
	if (!BN_is_zero(a) || !BN_is_one(b)) {
		BFIBEerr(BFIBE_F_BFIBE_SETUP, BFIBE_R_INVALID_TYPE1CURVE);
		goto end;
	}

	/* mpk->q = group->order */
	if (!EC_GROUP_get_order(group, mpk->q, bn_ctx)) {
		BFIBEerr(BFIBE_F_BFIBE_SETUP, BFIBE_R_INVALID_TYPE1CURVE);
		goto end;
	}

	/* mpk->pointP = group->generator */
	if (!EC_POINT_get_affine_coordinates_GFp(group, EC_GROUP_get0_generator(group),
		mpk->pointP->x, mpk->pointP->y, bn_ctx)) {
		BFIBEerr(BFIBE_F_BFIBE_SETUP, ERR_R_EC_LIB);
		goto end;
	}

	/* set mpk->hashfcn from F_p^2 element bits */
	OPENSSL_assert(mpk->hashfcn);
	ASN1_OBJECT_free(mpk->hashfcn);
	if (!(mpk->hashfcn = OBJ_nid2obj(EVP_MD_type(md)))) {
		BFIBEerr(BFIBE_F_BFIBE_SETUP, BFIBE_R_PARSE_PAIRING);
		goto end;
	}

	/*
	 * set msk->version
	 * random msk->masterSecret in [2, q - 1]
	 */

	msk->version = BFIBE_VERSION;

	do {
		if (!BN_rand_range(msk->masterSecret, mpk->q)) {
			BFIBEerr(BFIBE_F_BFIBE_SETUP, ERR_R_BN_LIB);
			goto end;
		}
	} while (BN_is_zero(msk->masterSecret) || BN_is_one(msk->masterSecret));

	/* mpk->pointPpub = msk->masterSecret * mpk->pointP */

	if (!EC_POINT_mul(group, point, msk->masterSecret, NULL, NULL, bn_ctx)) {
		BFIBEerr(BFIBE_F_BFIBE_SETUP, ERR_R_EC_LIB);
		goto end;
	}
	if (!EC_POINT_get_affine_coordinates_GFp(group, point,
		mpk->pointPpub->x, mpk->pointPpub->y, bn_ctx)) {
		BFIBEerr(BFIBE_F_BFIBE_SETUP, ERR_R_EC_LIB);
		goto end;
	}

	/* set return value */
	*pmpk = mpk;
	*pmsk = msk;
	ret = 1;

end:
	if (!ret) {
		BFPublicParameters_free(mpk);
		BFMasterSecret_free(msk);
		*pmpk = NULL;
		*pmsk = NULL;
	}
	if (bn_ctx) {
		BN_CTX_end(bn_ctx);
	}
	BN_CTX_free(bn_ctx);
	EC_POINT_free(point);
	return ret;
}
コード例 #19
0
ファイル: ec_lib.c プロジェクト: LucidOne/Rovio
int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx)
	{
	int    r = 0;
	BIGNUM *a1, *a2, *a3, *b1, *b2, *b3;
	BN_CTX *ctx_new = NULL;

	/* compare the field types*/
	if (EC_METHOD_get_field_type(EC_GROUP_method_of(a)) !=
	    EC_METHOD_get_field_type(EC_GROUP_method_of(b)))
		return 1;
	/* compare the curve name (if present) */
	if (EC_GROUP_get_curve_name(a) && EC_GROUP_get_curve_name(b) &&
	    EC_GROUP_get_curve_name(a) == EC_GROUP_get_curve_name(b))
		return 0;

	if (!ctx)
		ctx_new = ctx = BN_CTX_new();
	if (!ctx)
		return -1;
	
	BN_CTX_start(ctx);
	a1 = BN_CTX_get(ctx);
	a2 = BN_CTX_get(ctx);
	a3 = BN_CTX_get(ctx);
	b1 = BN_CTX_get(ctx);
	b2 = BN_CTX_get(ctx);
	b3 = BN_CTX_get(ctx);
	if (!b3)
		{
		BN_CTX_end(ctx);
		if (ctx_new)
			BN_CTX_free(ctx);
		return -1;
		}

	/* XXX This approach assumes that the external representation
	 * of curves over the same field type is the same.
	 */
	if (!a->meth->group_get_curve(a, a1, a2, a3, ctx) ||
	    !b->meth->group_get_curve(b, b1, b2, b3, ctx))
		r = 1;

	if (r || BN_cmp(a1, b1) || BN_cmp(a2, b2) || BN_cmp(a3, b3))
		r = 1;

	/* XXX EC_POINT_cmp() assumes that the methods are equal */
	if (r || EC_POINT_cmp(a, EC_GROUP_get0_generator(a),
	    EC_GROUP_get0_generator(b), ctx))
		r = 1;

	if (!r)
		{
		/* compare the order and cofactor */
		if (!EC_GROUP_get_order(a, a1, ctx) ||
		    !EC_GROUP_get_order(b, b1, ctx) ||
		    !EC_GROUP_get_cofactor(a, a2, ctx) ||
		    !EC_GROUP_get_cofactor(b, b2, ctx))
			{
			BN_CTX_end(ctx);
			if (ctx_new)
				BN_CTX_free(ctx);
			return -1;
			}
		if (BN_cmp(a1, b1) || BN_cmp(a2, b2))
			r = 1;
		}

	BN_CTX_end(ctx);
	if (ctx_new)
		BN_CTX_free(ctx);

	return r;
	}
コード例 #20
0
void Z_Gen(unsigned char *z, unsigned int klen, unsigned char *ID, unsigned char *x, unsigned char *y)
{
	// Tsp 需要
	// ZA=H256(ENTLA || IDA || a || b || xG || yG || xA || yA)。

	BN_CTX *ctx = NULL;
	ctx = BN_CTX_new();

	EC_KEY *ec_key = EC_KEY_new_by_curve_name(NID_sm2p256v1);
	const EC_GROUP *ec_group = EC_KEY_get0_group(ec_key);


	BIGNUM *p = NULL, *a = NULL, *b = NULL, *gen = NULL,
		*order = NULL, *cofactor = NULL;

	if ((p = BN_new()) == NULL || (a = BN_new()) == NULL ||
		(b = BN_new()) == NULL || (order = BN_new()) == NULL ||
		(cofactor = BN_new()) == NULL) {
			goto err;
	}

	int is_char_two = 0;
	int tmp_nid = EC_METHOD_get_field_type(EC_GROUP_method_of(ec_group));

	if (tmp_nid == NID_X9_62_characteristic_two_field)
		is_char_two = 1;

#ifndef OPENSSL_NO_EC2M
	if (is_char_two) {
		if (!EC_GROUP_get_curve_GF2m(ec_group, p, a, b, ctx)) {
			goto err;
		}
	} else  /* prime field */
#endif
	{
		if (!EC_GROUP_get_curve_GFp(ec_group, p, a, b, ctx)) {
			goto err;
		}
	}

	const EC_POINT *generator = EC_GROUP_get0_generator(ec_group);

	unsigned char g[65];
	EC_POINT_point2oct(ec_group, generator, POINT_CONVERSION_UNCOMPRESSED, g, ECDH_SIZE, NULL);

	sm3_ctx_t ctx2;

	sm3_init(&ctx2);
	unsigned char entla[2];
	entla[0] = (klen / 32);
	entla[1] = (klen * 8);
	sm3_update(&ctx2, entla, sizeof(entla));
	sm3_update(&ctx2, ID, klen);

	unsigned char buffer[32];
	BN_bn2bin(a, buffer);
	sm3_update(&ctx2, buffer, 32);
	BN_bn2bin(b, buffer);
	sm3_update(&ctx2, buffer, 32);

	sm3_update(&ctx2, g + 1, 64);
	sm3_update(&ctx2, x, 32);
	sm3_update(&ctx2, y, 32);
	sm3_final(&ctx2, z);

err:
	return;
}