Пример #1
0
/*
 * NIST SP800-56A co-factor ECDH tests.
 * KATs taken from NIST documents with parameters:
 *
 * - (QCAVSx,QCAVSy) is the public key for CAVS.
 * - dIUT is the private key for IUT.
 * - (QIUTx,QIUTy) is the public key for IUT.
 * - ZIUT is the shared secret KAT.
 *
 * CAVS: Cryptographic Algorithm Validation System
 * IUT: Implementation Under Test
 *
 * This function tests two things:
 *
 * 1. dIUT * G = (QIUTx,QIUTy)
 *    i.e. public key for IUT computes correctly.
 * 2. x-coord of cofactor * dIUT * (QCAVSx,QCAVSy) = ZIUT
 *    i.e. co-factor ECDH key computes correctly.
 *
 * returns zero on failure or unsupported curve. One otherwise.
 */
static int ecdh_cavs_kat(BIO *out, const ecdh_cavs_kat_t *kat)
{
    int rv = 0, is_char_two = 0;
    EC_KEY *key1 = NULL;
    EC_POINT *pub = NULL;
    const EC_GROUP *group = NULL;
    BIGNUM *bnz = NULL, *x = NULL, *y = NULL;
    unsigned char *Ztmp = NULL, *Z = NULL;
    size_t Ztmplen, Zlen;
    BIO_puts(out, "Testing ECC CDH Primitive SP800-56A with ");
    BIO_puts(out, OBJ_nid2sn(kat->nid));

    /* dIUT is IUT's private key */
    if ((key1 = mk_eckey(kat->nid, kat->dIUT)) == NULL)
        goto err;
    /* these are cofactor ECDH KATs */
    EC_KEY_set_flags(key1, EC_FLAG_COFACTOR_ECDH);

    if ((group = EC_KEY_get0_group(key1)) == NULL)
        goto err;
    if ((pub = EC_POINT_new(group)) == NULL)
        goto err;

    if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_characteristic_two_field)
        is_char_two = 1;

    /* (QIUTx, QIUTy) is IUT's public key */
    if(!BN_hex2bn(&x, kat->QIUTx))
        goto err;
    if(!BN_hex2bn(&y, kat->QIUTy))
        goto err;
    if (is_char_two) {
#ifdef OPENSSL_NO_EC2M
        goto err;
#else
        if (!EC_POINT_set_affine_coordinates_GF2m(group, pub, x, y, NULL))
            goto err;
#endif
    }
    else {
        if (!EC_POINT_set_affine_coordinates_GFp(group, pub, x, y, NULL))
            goto err;
    }
    /* dIUT * G = (QIUTx, QIUTy) should hold */
    if (EC_POINT_cmp(group, EC_KEY_get0_public_key(key1), pub, NULL))
        goto err;

    /* (QCAVSx, QCAVSy) is CAVS's public key */
    if(!BN_hex2bn(&x, kat->QCAVSx))
        goto err;
    if(!BN_hex2bn(&y, kat->QCAVSy))
        goto err;
    if (is_char_two) {
#ifdef OPENSSL_NO_EC2M
        goto err;
#else
        if (!EC_POINT_set_affine_coordinates_GF2m(group, pub, x, y, NULL))
            goto err;
#endif
    }
    else {
        if (!EC_POINT_set_affine_coordinates_GFp(group, pub, x, y, NULL))
            goto err;
    }

    /* ZIUT is the shared secret */
    if(!BN_hex2bn(&bnz, kat->ZIUT))
        goto err;
    Ztmplen = (EC_GROUP_get_degree(EC_KEY_get0_group(key1)) + 7) / 8;
    Zlen = BN_num_bytes(bnz);
    if (Zlen > Ztmplen)
        goto err;
    if((Ztmp = OPENSSL_zalloc(Ztmplen)) == NULL)
        goto err;
    if((Z = OPENSSL_zalloc(Ztmplen)) == NULL)
        goto err;
    if(!BN_bn2binpad(bnz, Z, Ztmplen))
        goto err;
    if (!ECDH_compute_key(Ztmp, Ztmplen, pub, key1, 0))
        goto err;
    /* shared secrets should be identical */
    if (memcmp(Ztmp, Z, Ztmplen))
        goto err;
    rv = 1;
 err:
    EC_KEY_free(key1);
    EC_POINT_free(pub);
    BN_free(bnz);
    BN_free(x);
    BN_free(y);
    OPENSSL_free(Ztmp);
    OPENSSL_free(Z);
    if (rv) {
        BIO_puts(out, " ok\n");
    }
    else {
        fprintf(stderr, "Error in ECC CDH routines\n");
        ERR_print_errors_fp(stderr);
    }
    return rv;
}
Пример #2
0
int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x,
                                             BIGNUM *y)
{
    BN_CTX *ctx = NULL;
    BIGNUM *tx, *ty;
    EC_POINT *point = NULL;
    int ok = 0;
#ifndef OPENSSL_NO_EC2M
    int tmp_nid, is_char_two = 0;
#endif

    if (key == NULL || key->group == NULL || x == NULL || y == NULL) {
        ECerr(EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES,
              ERR_R_PASSED_NULL_PARAMETER);
        return 0;
    }
    ctx = BN_CTX_new();
    if (ctx == NULL)
        return 0;

    BN_CTX_start(ctx);
    point = EC_POINT_new(key->group);

    if (point == NULL)
        goto err;

    tx = BN_CTX_get(ctx);
    ty = BN_CTX_get(ctx);
    if (ty == NULL)
        goto err;

#ifndef OPENSSL_NO_EC2M
    tmp_nid = EC_METHOD_get_field_type(EC_GROUP_method_of(key->group));

    if (tmp_nid == NID_X9_62_characteristic_two_field)
        is_char_two = 1;

    if (is_char_two) {
        if (!EC_POINT_set_affine_coordinates_GF2m(key->group, point,
                                                  x, y, ctx))
            goto err;
        if (!EC_POINT_get_affine_coordinates_GF2m(key->group, point,
                                                  tx, ty, ctx))
            goto err;
    } else
#endif
    {
        if (!EC_POINT_set_affine_coordinates_GFp(key->group, point,
                                                 x, y, ctx))
            goto err;
        if (!EC_POINT_get_affine_coordinates_GFp(key->group, point,
                                                 tx, ty, ctx))
            goto err;
    }
    /*
     * Check if retrieved coordinates match originals and are less than field
     * order: if not values are out of range.
     */
    if (BN_cmp(x, tx) || BN_cmp(y, ty)
        || (BN_cmp(x, key->group->field) >= 0)
        || (BN_cmp(y, key->group->field) >= 0)) {
        ECerr(EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES,
              EC_R_COORDINATES_OUT_OF_RANGE);
        goto err;
    }

    if (!EC_KEY_set_public_key(key, point))
        goto err;

    if (EC_KEY_check_key(key) == 0)
        goto err;

    ok = 1;

 err:
    BN_CTX_end(ctx);
    BN_CTX_free(ctx);
    EC_POINT_free(point);
    return ok;

}
Пример #3
0
/* Computes a + b and stores the result in r.  r could be a or b, a could be b.
 * Uses algorithm A.10.2 of IEEE P1363.
 */
int ec_GF2m_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx)
	{
	BN_CTX *new_ctx = NULL;
	BIGNUM *x0, *y0, *x1, *y1, *x2, *y2, *s, *t;
	int ret = 0;
	
	if (EC_POINT_is_at_infinity(group, a))
		{
		if (!EC_POINT_copy(r, b)) return 0;
		return 1;
		}

	if (EC_POINT_is_at_infinity(group, b))
		{
		if (!EC_POINT_copy(r, a)) return 0;
		return 1;
		}

	if (ctx == NULL)
		{
		ctx = new_ctx = BN_CTX_new();
		if (ctx == NULL)
			return 0;
		}

	BN_CTX_start(ctx);
	x0 = BN_CTX_get(ctx);
	y0 = BN_CTX_get(ctx);
	x1 = BN_CTX_get(ctx);
	y1 = BN_CTX_get(ctx);
	x2 = BN_CTX_get(ctx);
	y2 = BN_CTX_get(ctx);
	s = BN_CTX_get(ctx);
	t = BN_CTX_get(ctx);
	if (t == NULL) goto err;

	if (a->Z_is_one) 
		{
		if (!BN_copy(x0, &a->X)) goto err;
		if (!BN_copy(y0, &a->Y)) goto err;
		}
	else
		{
		if (!EC_POINT_get_affine_coordinates_GF2m(group, a, x0, y0, ctx)) goto err;
		}
	if (b->Z_is_one) 
		{
		if (!BN_copy(x1, &b->X)) goto err;
		if (!BN_copy(y1, &b->Y)) goto err;
		}
	else
		{
		if (!EC_POINT_get_affine_coordinates_GF2m(group, b, x1, y1, ctx)) goto err;
		}


	if (BN_GF2m_cmp(x0, x1))
		{
		if (!BN_GF2m_add(t, x0, x1)) goto err;
		if (!BN_GF2m_add(s, y0, y1)) goto err;
		if (!group->meth->field_div(group, s, s, t, ctx)) goto err;
		if (!group->meth->field_sqr(group, x2, s, ctx)) goto err;
		if (!BN_GF2m_add(x2, x2, &group->a)) goto err;
		if (!BN_GF2m_add(x2, x2, s)) goto err;
		if (!BN_GF2m_add(x2, x2, t)) goto err;
		}
	else
		{
		if (BN_GF2m_cmp(y0, y1) || BN_is_zero(x1))
			{
			if (!EC_POINT_set_to_infinity(group, r)) goto err;
			ret = 1;
			goto err;
			}
		if (!group->meth->field_div(group, s, y1, x1, ctx)) goto err;
		if (!BN_GF2m_add(s, s, x1)) goto err;
		
		if (!group->meth->field_sqr(group, x2, s, ctx)) goto err;
		if (!BN_GF2m_add(x2, x2, s)) goto err;
		if (!BN_GF2m_add(x2, x2, &group->a)) goto err;
		}

	if (!BN_GF2m_add(y2, x1, x2)) goto err;
	if (!group->meth->field_mul(group, y2, y2, s, ctx)) goto err;
	if (!BN_GF2m_add(y2, y2, x2)) goto err;
	if (!BN_GF2m_add(y2, y2, y1)) goto err;

	if (!EC_POINT_set_affine_coordinates_GF2m(group, r, x2, y2, ctx)) goto err;

	ret = 1;

 err:
	BN_CTX_end(ctx);
	if (new_ctx != NULL)
		BN_CTX_free(new_ctx);
	return ret;
	}
Пример #4
0
void char2_field_tests()
	{	
	BN_CTX *ctx = NULL;
	BIGNUM *p, *a, *b;
	EC_GROUP *group;
	EC_GROUP *C2_K163 = NULL, *C2_K233 = NULL, *C2_K283 = NULL, *C2_K409 = NULL, *C2_K571 = NULL;
	EC_GROUP *C2_B163 = NULL, *C2_B233 = NULL, *C2_B283 = NULL, *C2_B409 = NULL, *C2_B571 = NULL;
	EC_POINT *P, *Q, *R;
	BIGNUM *x, *y, *z, *cof;
	unsigned char buf[100];
	size_t i, len;
	int k;
	
#if 1 /* optional */
	ctx = BN_CTX_new();
	if (!ctx) ABORT;
#endif

	p = BN_new();
	a = BN_new();
	b = BN_new();
	if (!p || !a || !b) ABORT;

	if (!BN_hex2bn(&p, "13")) ABORT;
	if (!BN_hex2bn(&a, "3")) ABORT;
	if (!BN_hex2bn(&b, "1")) ABORT;
	
	group = EC_GROUP_new(EC_GF2m_simple_method()); /* applications should use EC_GROUP_new_curve_GF2m
	                                                * so that the library gets to choose the EC_METHOD */
	if (!group) ABORT;
	if (!EC_GROUP_set_curve_GF2m(group, p, a, b, ctx)) ABORT;

	{
		EC_GROUP *tmp;
		tmp = EC_GROUP_new(EC_GROUP_method_of(group));
		if (!tmp) ABORT;
		if (!EC_GROUP_copy(tmp, group)) ABORT;
		EC_GROUP_free(group);
		group = tmp;
	}
	
	if (!EC_GROUP_get_curve_GF2m(group, p, a, b, ctx)) ABORT;

	fprintf(stdout, "Curve defined by Weierstrass equation\n     y^2 + x*y = x^3 + a*x^2 + b  (mod 0x");
	BN_print_fp(stdout, p);
	fprintf(stdout, ")\n     a = 0x");
	BN_print_fp(stdout, a);
	fprintf(stdout, "\n     b = 0x");
	BN_print_fp(stdout, b);
	fprintf(stdout, "\n(0x... means binary polynomial)\n");

	P = EC_POINT_new(group);
	Q = EC_POINT_new(group);
	R = EC_POINT_new(group);
	if (!P || !Q || !R) ABORT;
	
	if (!EC_POINT_set_to_infinity(group, P)) ABORT;
	if (!EC_POINT_is_at_infinity(group, P)) ABORT;

	buf[0] = 0;
	if (!EC_POINT_oct2point(group, Q, buf, 1, ctx)) ABORT;

	if (!EC_POINT_add(group, P, P, Q, ctx)) ABORT;
	if (!EC_POINT_is_at_infinity(group, P)) ABORT;

	x = BN_new();
	y = BN_new();
	z = BN_new();
	cof = BN_new();
	if (!x || !y || !z || !cof) ABORT;

	if (!BN_hex2bn(&x, "6")) ABORT;
/* Change test based on whether binary point compression is enabled or not. */
#ifdef OPENSSL_EC_BIN_PT_COMP
	if (!EC_POINT_set_compressed_coordinates_GF2m(group, Q, x, 1, ctx)) ABORT;
#else
	if (!BN_hex2bn(&y, "8")) ABORT;
	if (!EC_POINT_set_affine_coordinates_GF2m(group, Q, x, y, ctx)) ABORT;
#endif
	if (!EC_POINT_is_on_curve(group, Q, ctx))
		{
/* Change test based on whether binary point compression is enabled or not. */
#ifdef OPENSSL_EC_BIN_PT_COMP
		if (!EC_POINT_get_affine_coordinates_GF2m(group, Q, x, y, ctx)) ABORT;
#endif
		fprintf(stderr, "Point is not on curve: x = 0x");
		BN_print_fp(stderr, x);
		fprintf(stderr, ", y = 0x");
		BN_print_fp(stderr, y);
		fprintf(stderr, "\n");
		ABORT;
		}

	fprintf(stdout, "A cyclic subgroup:\n");
	k = 100;
	do
		{
		if (k-- == 0) ABORT;

		if (EC_POINT_is_at_infinity(group, P))
			fprintf(stdout, "     point at infinity\n");
		else
			{
			if (!EC_POINT_get_affine_coordinates_GF2m(group, P, x, y, ctx)) ABORT;

			fprintf(stdout, "     x = 0x");
			BN_print_fp(stdout, x);
			fprintf(stdout, ", y = 0x");
			BN_print_fp(stdout, y);
			fprintf(stdout, "\n");
			}
		
		if (!EC_POINT_copy(R, P)) ABORT;
		if (!EC_POINT_add(group, P, P, Q, ctx)) ABORT;
		}
	while (!EC_POINT_is_at_infinity(group, P));

	if (!EC_POINT_add(group, P, Q, R, ctx)) ABORT;
	if (!EC_POINT_is_at_infinity(group, P)) ABORT;

/* Change test based on whether binary point compression is enabled or not. */
#ifdef OPENSSL_EC_BIN_PT_COMP
	len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_COMPRESSED, buf, sizeof buf, ctx);
	if (len == 0) ABORT;
	if (!EC_POINT_oct2point(group, P, buf, len, ctx)) ABORT;
	if (0 != EC_POINT_cmp(group, P, Q, ctx)) ABORT;
	fprintf(stdout, "Generator as octet string, compressed form:\n     ");
	for (i = 0; i < len; i++) fprintf(stdout, "%02X", buf[i]);
#endif
	
	len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_UNCOMPRESSED, buf, sizeof buf, ctx);
	if (len == 0) ABORT;
	if (!EC_POINT_oct2point(group, P, buf, len, ctx)) ABORT;
	if (0 != EC_POINT_cmp(group, P, Q, ctx)) ABORT;
	fprintf(stdout, "\nGenerator as octet string, uncompressed form:\n     ");
	for (i = 0; i < len; i++) fprintf(stdout, "%02X", buf[i]);
	
/* Change test based on whether binary point compression is enabled or not. */
#ifdef OPENSSL_EC_BIN_PT_COMP
	len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_HYBRID, buf, sizeof buf, ctx);
	if (len == 0) ABORT;
	if (!EC_POINT_oct2point(group, P, buf, len, ctx)) ABORT;
	if (0 != EC_POINT_cmp(group, P, Q, ctx)) ABORT;
	fprintf(stdout, "\nGenerator as octet string, hybrid form:\n     ");
	for (i = 0; i < len; i++) fprintf(stdout, "%02X", buf[i]);
#endif

	fprintf(stdout, "\n");
	
	if (!EC_POINT_invert(group, P, ctx)) ABORT;
	if (0 != EC_POINT_cmp(group, P, R, ctx)) ABORT;


	/* Curve K-163 (FIPS PUB 186-2, App. 6) */
	CHAR2_CURVE_TEST
		(
		"NIST curve K-163",
		"0800000000000000000000000000000000000000C9",
		"1",
		"1",
		"02FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE8",
		"0289070FB05D38FF58321F2E800536D538CCDAA3D9",
		1,
		"04000000000000000000020108A2E0CC0D99F8A5EF",
		"2",
		163,
		C2_K163
		);

	/* Curve B-163 (FIPS PUB 186-2, App. 6) */
	CHAR2_CURVE_TEST
		(
		"NIST curve B-163",
		"0800000000000000000000000000000000000000C9",
		"1",
		"020A601907B8C953CA1481EB10512F78744A3205FD",
		"03F0EBA16286A2D57EA0991168D4994637E8343E36",
		"00D51FBC6C71A0094FA2CDD545B11C5C0C797324F1",
		1,
		"040000000000000000000292FE77E70C12A4234C33",
		"2",
		163,
		C2_B163
		);

	/* Curve K-233 (FIPS PUB 186-2, App. 6) */
	CHAR2_CURVE_TEST
		(
		"NIST curve K-233",
		"020000000000000000000000000000000000000004000000000000000001",
		"0",
		"1",
		"017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD6126",
		"01DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3",
		0,
		"008000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF",
		"4",
		233,
		C2_K233
		);

	/* Curve B-233 (FIPS PUB 186-2, App. 6) */
	CHAR2_CURVE_TEST
		(
		"NIST curve B-233",
		"020000000000000000000000000000000000000004000000000000000001",
		"000000000000000000000000000000000000000000000000000000000001",
		"0066647EDE6C332C7F8C0923BB58213B333B20E9CE4281FE115F7D8F90AD",
		"00FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B",
		"01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052",
		1,
		"01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7",
		"2",
		233,
		C2_B233
		);

	/* Curve K-283 (FIPS PUB 186-2, App. 6) */
	CHAR2_CURVE_TEST
		(
		"NIST curve K-283",
		"0800000000000000000000000000000000000000000000000000000000000000000010A1",
		"0",
		"1",
		"0503213F78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836",
		"01CCDA380F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259",
		0,
		"01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163C61",
		"4",
		283,
		C2_K283
		);

	/* Curve B-283 (FIPS PUB 186-2, App. 6) */
	CHAR2_CURVE_TEST
		(
		"NIST curve B-283",
		"0800000000000000000000000000000000000000000000000000000000000000000010A1",
		"000000000000000000000000000000000000000000000000000000000000000000000001",
		"027B680AC8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A2F5",
		"05F939258DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053",
		"03676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4",
		1,
		"03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307",
		"2",
		283,
		C2_B283
		);

	/* Curve K-409 (FIPS PUB 186-2, App. 6) */
	CHAR2_CURVE_TEST
		(
		"NIST curve K-409",
		"02000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000001",
		"0",
		"1",
		"0060F05F658F49C1AD3AB1890F7184210EFD0987E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746",
		"01E369050B7C4E42ACBA1DACBF04299C3460782F918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B",
		1,
		"007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5F83B2D4EA20400EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF",
		"4",
		409,
		C2_K409
		);

	/* Curve B-409 (FIPS PUB 186-2, App. 6) */
	CHAR2_CURVE_TEST
		(
		"NIST curve B-409",
		"02000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000001",
		"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
		"0021A5C2C8EE9FEB5C4B9A753B7B476B7FD6422EF1F3DD674761FA99D6AC27C8A9A197B272822F6CD57A55AA4F50AE317B13545F",
		"015D4860D088DDB3496B0C6064756260441CDE4AF1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A7",
		"0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706",
		1,
		"010000000000000000000000000000000000000000000000000001E2AAD6A612F33307BE5FA47C3C9E052F838164CD37D9A21173",
		"2",
		409,
		C2_B409
		);

	/* Curve K-571 (FIPS PUB 186-2, App. 6) */
	CHAR2_CURVE_TEST
		(
		"NIST curve K-571",
		"80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000425",
		"0",
		"1",
		"026EB7A859923FBC82189631F8103FE4AC9CA2970012D5D46024804801841CA44370958493B205E647DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972",
		"0349DC807F4FBF374F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0AC44AEA74FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3",
		0,
		"020000000000000000000000000000000000000000000000000000000000000000000000131850E1F19A63E4B391A8DB917F4138B630D84BE5D639381E91DEB45CFE778F637C1001",
		"4",
		571,
		C2_K571
		);

	/* Curve B-571 (FIPS PUB 186-2, App. 6) */
	CHAR2_CURVE_TEST
		(
		"NIST curve B-571",
		"80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000425",
		"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
		"02F40E7E2221F295DE297117B7F3D62F5C6A97FFCB8CEFF1CD6BA8CE4A9A18AD84FFABBD8EFA59332BE7AD6756A66E294AFD185A78FF12AA520E4DE739BACA0C7FFEFF7F2955727A",
		"0303001D34B856296C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950F4C0D293CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19",
		"037BF27342DA639B6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43BAB08A576291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B",
		1,
		"03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE661CE18FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2FE84E47",
		"2",
		571,
		C2_B571
		);

	/* more tests using the last curve */

	if (!EC_POINT_copy(Q, P)) ABORT;
	if (EC_POINT_is_at_infinity(group, Q)) ABORT;
	if (!EC_POINT_dbl(group, P, P, ctx)) ABORT;
	if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
	if (!EC_POINT_invert(group, Q, ctx)) ABORT; /* P = -2Q */

	if (!EC_POINT_add(group, R, P, Q, ctx)) ABORT;
	if (!EC_POINT_add(group, R, R, Q, ctx)) ABORT;
	if (!EC_POINT_is_at_infinity(group, R)) ABORT; /* R = P + 2Q */

	{
		const EC_POINT *points[3];
		const BIGNUM *scalars[3];
	
		if (EC_POINT_is_at_infinity(group, Q)) ABORT;
		points[0] = Q;
		points[1] = Q;
		points[2] = Q;

		if (!BN_add(y, z, BN_value_one())) ABORT;
		if (BN_is_odd(y)) ABORT;
		if (!BN_rshift1(y, y)) ABORT;
		scalars[0] = y; /* (group order + 1)/2,  so  y*Q + y*Q = Q */
		scalars[1] = y;

		fprintf(stdout, "combined multiplication ...");
		fflush(stdout);

		/* z is still the group order */
		if (!EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx)) ABORT;
		if (!EC_POINTs_mul(group, R, z, 2, points, scalars, ctx)) ABORT;
		if (0 != EC_POINT_cmp(group, P, R, ctx)) ABORT;
		if (0 != EC_POINT_cmp(group, R, Q, ctx)) ABORT;

		fprintf(stdout, ".");
		fflush(stdout);

		if (!BN_pseudo_rand(y, BN_num_bits(y), 0, 0)) ABORT;
		if (!BN_add(z, z, y)) ABORT;
		BN_set_negative(z, 1);
		scalars[0] = y;
		scalars[1] = z; /* z = -(order + y) */

		if (!EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx)) ABORT;
		if (!EC_POINT_is_at_infinity(group, P)) ABORT;

		fprintf(stdout, ".");
		fflush(stdout);

		if (!BN_pseudo_rand(x, BN_num_bits(y) - 1, 0, 0)) ABORT;
		if (!BN_add(z, x, y)) ABORT;
		BN_set_negative(z, 1);
		scalars[0] = x;
		scalars[1] = y;
		scalars[2] = z; /* z = -(x+y) */

		if (!EC_POINTs_mul(group, P, NULL, 3, points, scalars, ctx)) ABORT;
		if (!EC_POINT_is_at_infinity(group, P)) ABORT;

		fprintf(stdout, " ok\n\n");
	}


#if 0
	timings(C2_K163, TIMING_BASE_PT, ctx);
	timings(C2_K163, TIMING_RAND_PT, ctx);
	timings(C2_K163, TIMING_SIMUL, ctx);
	timings(C2_B163, TIMING_BASE_PT, ctx);
	timings(C2_B163, TIMING_RAND_PT, ctx);
	timings(C2_B163, TIMING_SIMUL, ctx);
	timings(C2_K233, TIMING_BASE_PT, ctx);
	timings(C2_K233, TIMING_RAND_PT, ctx);
	timings(C2_K233, TIMING_SIMUL, ctx);
	timings(C2_B233, TIMING_BASE_PT, ctx);
	timings(C2_B233, TIMING_RAND_PT, ctx);
	timings(C2_B233, TIMING_SIMUL, ctx);
	timings(C2_K283, TIMING_BASE_PT, ctx);
	timings(C2_K283, TIMING_RAND_PT, ctx);
	timings(C2_K283, TIMING_SIMUL, ctx);
	timings(C2_B283, TIMING_BASE_PT, ctx);
	timings(C2_B283, TIMING_RAND_PT, ctx);
	timings(C2_B283, TIMING_SIMUL, ctx);
	timings(C2_K409, TIMING_BASE_PT, ctx);
	timings(C2_K409, TIMING_RAND_PT, ctx);
	timings(C2_K409, TIMING_SIMUL, ctx);
	timings(C2_B409, TIMING_BASE_PT, ctx);
	timings(C2_B409, TIMING_RAND_PT, ctx);
	timings(C2_B409, TIMING_SIMUL, ctx);
	timings(C2_K571, TIMING_BASE_PT, ctx);
	timings(C2_K571, TIMING_RAND_PT, ctx);
	timings(C2_K571, TIMING_SIMUL, ctx);
	timings(C2_B571, TIMING_BASE_PT, ctx);
	timings(C2_B571, TIMING_RAND_PT, ctx);
	timings(C2_B571, TIMING_SIMUL, ctx);
#endif


	if (ctx)
		BN_CTX_free(ctx);
	BN_free(p); BN_free(a);	BN_free(b);
	EC_GROUP_free(group);
	EC_POINT_free(P);
	EC_POINT_free(Q);
	EC_POINT_free(R);
	BN_free(x); BN_free(y); BN_free(z); BN_free(cof);

	if (C2_K163) EC_GROUP_free(C2_K163);
	if (C2_B163) EC_GROUP_free(C2_B163);
	if (C2_K233) EC_GROUP_free(C2_K233);
	if (C2_B233) EC_GROUP_free(C2_B233);
	if (C2_K283) EC_GROUP_free(C2_K283);
	if (C2_B283) EC_GROUP_free(C2_B283);
	if (C2_K409) EC_GROUP_free(C2_K409);
	if (C2_B409) EC_GROUP_free(C2_B409);
	if (C2_K571) EC_GROUP_free(C2_K571);
	if (C2_B571) EC_GROUP_free(C2_B571);

	}
Пример #5
0
static EC_GROUP *ec_group_new_from_data(const EC_CURVE_DATA *data)
	{
	EC_GROUP *group=NULL;
	EC_POINT *P=NULL;
	BN_CTX	 *ctx=NULL;
	BIGNUM 	 *p=NULL, *a=NULL, *b=NULL, *x=NULL, *y=NULL, *order=NULL;
	int	 ok=0;

	if ((ctx = BN_CTX_new()) == NULL)
		{
		ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_MALLOC_FAILURE);
		goto err;
		}
	if ((p = BN_new()) == NULL || (a = BN_new()) == NULL || 
		(b = BN_new()) == NULL || (x = BN_new()) == NULL ||
		(y = BN_new()) == NULL || (order = BN_new()) == NULL)
		{
		ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_MALLOC_FAILURE);
		goto err;
		}
	
	if (!BN_hex2bn(&p, data->p) || !BN_hex2bn(&a, data->a)
		|| !BN_hex2bn(&b, data->b))
		{
		ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB);
		goto err;
		}

	if (data->field_type == NID_X9_62_prime_field)
		{
		if ((group = EC_GROUP_new_curve_GFp(p, a, b, ctx)) == NULL)
			{
			ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
			goto err;
			}
		}
		else
		{ /* field_type == NID_X9_62_characteristic_two_field */
		if ((group = EC_GROUP_new_curve_GF2m(p, a, b, ctx)) == NULL)
			{
			ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
			goto err;
			}
		}

	if ((P = EC_POINT_new(group)) == NULL)
		{
		ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
		goto err;
		}
	
	if (!BN_hex2bn(&x, data->x) || !BN_hex2bn(&y, data->y))
		{
		ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB);
		goto err;
		}
	if (!EC_POINT_set_affine_coordinates_GF2m(group, P, x, y, ctx))
		{
		ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
		goto err;
		}
	if (!BN_hex2bn(&order, data->order) || !BN_set_word(x, data->cofactor))
		{
		ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB);
		goto err;
		}
	if (!EC_GROUP_set_generator(group, P, order, x))
		{
		ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
		goto err;
		}
	if (data->seed)
		{
		if (!EC_GROUP_set_seed(group, data->seed, data->seed_len))
			{
			ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
			goto err;
			}
		}
	ok=1;
err:
	if (!ok)
		{
		EC_GROUP_free(group);
		group = NULL;
		}
	if (P)
		EC_POINT_free(P);
	if (ctx)
		BN_CTX_free(ctx);
	if (p)
		BN_free(p);
	if (a)
		BN_free(a);
	if (b)
		BN_free(b);
	if (order)
		BN_free(order);
	if (x)
		BN_free(x);
	if (y)
		BN_free(y);
	return group;
	}
Пример #6
0
int SM2_do_decrypt(const EVP_MD *md, const SM2CiphertextValue *cv,
	unsigned char *out, size_t *outlen, EC_KEY *ec_key)
{
	int ret = 0;
	const EC_GROUP *group;
	const BIGNUM *pri_key;
	KDF_FUNC kdf;
	EC_POINT *point = NULL;
	EC_POINT *tmp_point = NULL;
	BIGNUM *n = NULL;
	BIGNUM *h = NULL;
	BN_CTX *bn_ctx = NULL;
	EVP_MD_CTX *md_ctx = NULL;
	unsigned char buf[(OPENSSL_ECC_MAX_FIELD_BITS + 7)/4 + 1];
	unsigned char mac[EVP_MAX_MD_SIZE];
	unsigned int maclen = sizeof(mac);
	int nbytes, len, i;

	/* check arguments */
	if (!md || !cv || !outlen || !ec_key) {
		SM2err(SM2_F_SM2_DO_DECRYPT, ERR_R_PASSED_NULL_PARAMETER);
		return 0;
	}

	if (!(kdf = KDF_get_x9_63(md))) {
		SM2err(SM2_F_SM2_DO_DECRYPT, SM2_R_INVALID_DIGEST_ALGOR);
		return 0;
	}

	if (!cv->xCoordinate || !cv->yCoordinate || !cv->hash || !cv->ciphertext) {
		SM2err(SM2_F_SM2_DO_DECRYPT, SM2_R_INVALID_CIPHERTEXT);
		return 0;
	}

	if (cv->hash->length != EVP_MD_size(md)) {
		SM2err(SM2_F_SM2_DO_DECRYPT, SM2_R_INVALID_CIPHERTEXT);
		return 0;
	}

	if (cv->ciphertext->length < SM2_MIN_PLAINTEXT_LENGTH
		|| cv->ciphertext->length > SM2_MAX_PLAINTEXT_LENGTH) {
		SM2err(SM2_F_SM2_DO_DECRYPT, SM2_R_INVALID_CIPHERTEXT);
		return 0;
	}

	if (!(group = EC_KEY_get0_group(ec_key))
		|| !(pri_key = EC_KEY_get0_private_key(ec_key))) {
		SM2err(SM2_F_SM2_DO_DECRYPT, SM2_R_INVALID_EC_KEY);
		return 0;
	}

	if (!out) {
		*outlen = cv->ciphertext->length;
		return 1;
	}
	if (*outlen < cv->ciphertext->length) {
		SM2err(SM2_F_SM2_DO_DECRYPT, SM2_R_BUFFER_TOO_SMALL);
		return 0;
	}

	/* malloc */
	point = EC_POINT_new(group);
	tmp_point = EC_POINT_new(group);
	n = BN_new();
	h = BN_new();
	bn_ctx = BN_CTX_new();
	md_ctx = EVP_MD_CTX_new();
	if (!point || !n || !h || !bn_ctx || !md_ctx) {
		SM2err(SM2_F_SM2_DO_DECRYPT, ERR_R_MALLOC_FAILURE);
		goto end;
	}

	/* init ec domain parameters */
	if (!EC_GROUP_get_order(group, n, bn_ctx)) {
		SM2err(SM2_F_SM2_DO_DECRYPT, ERR_R_EC_LIB);
		goto end;
	}

	if (!EC_GROUP_get_cofactor(group, h, bn_ctx)) {
		SM2err(SM2_F_SM2_DO_DECRYPT, ERR_R_EC_LIB);
		goto end;
	}

	nbytes = (EC_GROUP_get_degree(group) + 7) / 8;

	/* get x/yCoordinates as C1 = (x1, y1) */
	if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field) {
		if (!EC_POINT_set_affine_coordinates_GFp(group, point,
			cv->xCoordinate, cv->yCoordinate, bn_ctx)) {
			SM2err(SM2_F_SM2_DO_DECRYPT, SM2_R_INVALID_CIPHERTEXT);
			goto end;
		}
	} else {
		if (!EC_POINT_set_affine_coordinates_GF2m(group, point,
			cv->xCoordinate, cv->yCoordinate, bn_ctx)) {
			SM2err(SM2_F_SM2_DO_DECRYPT, SM2_R_INVALID_CIPHERTEXT);
			goto end;
		}
	}

	/* check [h]C1 != O */
	if (!EC_POINT_mul(group, tmp_point, NULL, point, h, bn_ctx)) {
		SM2err(SM2_F_SM2_DO_DECRYPT, ERR_R_EC_LIB);
		goto end;
	}

	if (EC_POINT_is_at_infinity(group, tmp_point)) {
		SM2err(SM2_F_SM2_DO_DECRYPT, SM2_R_INVALID_CIPHERTEXT);
		goto end;
	}

	/* compute ECDH [d]C1 = (x2, y2) */
	if (!EC_POINT_mul(group, point, NULL, point, pri_key, bn_ctx)) {
		SM2err(SM2_F_SM2_DO_DECRYPT, ERR_R_EC_LIB);
		goto end;
	}

	if (!(len = EC_POINT_point2oct(group, point,
		POINT_CONVERSION_UNCOMPRESSED, buf, sizeof(buf), bn_ctx))) {
		SM2err(SM2_F_SM2_DO_DECRYPT, ERR_R_EC_LIB);
		goto end;
	}

	/* compute t = KDF(x2 || y2, clen) */
	*outlen = cv->ciphertext->length;
	kdf(buf + 1, len - 1, out, outlen);


	/* compute M = C2 xor t */
	for (i = 0; i < cv->ciphertext->length; i++) {
		out[i] ^= cv->ciphertext->data[i];
	}

	/* check hash == Hash(x2 || M || y2) */
	if (!EVP_DigestInit_ex(md_ctx, md, NULL)
		|| !EVP_DigestUpdate(md_ctx, buf + 1, nbytes)
		|| !EVP_DigestUpdate(md_ctx, out, *outlen)
		|| !EVP_DigestUpdate(md_ctx, buf + 1 + nbytes, nbytes)
		|| !EVP_DigestFinal_ex(md_ctx, mac, &maclen)) {
		SM2err(SM2_F_SM2_DO_DECRYPT, ERR_R_EVP_LIB);
		goto end;
	}

	if (OPENSSL_memcmp(cv->hash->data, mac, maclen) != 0) {
		SM2err(SM2_F_SM2_DO_DECRYPT, SM2_R_INVALID_CIPHERTEXT);
		goto end;
	}

	ret = 1;
end:
	EC_POINT_free(point);
	EC_POINT_free(tmp_point);
	BN_free(n);
	BN_free(h);
	BN_CTX_free(bn_ctx);
	EVP_MD_CTX_free(md_ctx);
	return ret;
}