EC_GROUP * ECDSAKeyPair::createGroup(const EllipticCurve& curve) {
	BN_CTX *ctx;
	EC_GROUP *group;
	EC_POINT *generator;

	/* Set up the BN_CTX */
	ctx = BN_CTX_new();
	if (ctx == NULL){
		throw AsymmetricKeyException(AsymmetricKeyException::INTERNAL_ERROR,
				"Failed to create BN_CTX", "ECDSAKeyPair::createGroup");
	}

	/* Create the curve */
	group = EC_GROUP_new_curve_GFp(curve.BN_p(), curve.BN_a(),	curve.BN_b(), ctx);
	if (group == NULL) {
		BN_CTX_free(ctx);
		throw AsymmetricKeyException(AsymmetricKeyException::INTERNAL_ERROR,
				"Failed to create group", "ECDSAKeyPair::createGroup");
	}

	/* Create the generator */
	generator = EC_POINT_new(group);
	if (generator == NULL) {
		BN_CTX_free(ctx);
		EC_GROUP_free(group);
		throw AsymmetricKeyException(AsymmetricKeyException::INTERNAL_ERROR,
				"Failed to create generator", "ECDSAKeyPair::createGroup");
	}

	if (1 != EC_POINT_set_affine_coordinates_GFp(group, generator, curve.BN_x(), curve.BN_y(), ctx)) {
		BN_CTX_free(ctx);
		EC_GROUP_free(group);
		throw AsymmetricKeyException(AsymmetricKeyException::INTERNAL_ERROR,
				"Failed to set the affine coordinates of a EC_POINT over GFp",
				"ECDSAKeyPair::createGroup");
	}

	/* Set the generator and the order */
	if (1 != EC_GROUP_set_generator(group, generator, curve.BN_order(),	curve.BN_cofactor())) {
		BN_CTX_free(ctx);
		EC_GROUP_free(group);
		EC_POINT_free(generator);
		throw AsymmetricKeyException(AsymmetricKeyException::INTERNAL_ERROR,
				"Failed to set generator and order", "ECDSAKeyPair::createGroup");
	}

	EC_POINT_free(generator);
	BN_CTX_free(ctx);

	return group;
}
Beispiel #2
0
int GOST_KEY_set_public_key_affine_coordinates(GOST_KEY *key, BIGNUM *x, BIGNUM *y)
{
    BN_CTX *ctx = NULL;
    BIGNUM *tx, *ty;
    EC_POINT *point = NULL;
    int ok = 0;

    if (key == NULL || key->group == NULL || x == NULL || y == NULL) {
        GOSTerr(GOST_F_GOST_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES,
                ERR_R_PASSED_NULL_PARAMETER);
        return 0;
    }
    ctx = BN_CTX_new();
    if (ctx == NULL)
        goto err;

    point = EC_POINT_new(key->group);
    if (point == NULL)
        goto err;

    if ((tx = BN_CTX_get(ctx)) == NULL)
        goto err;
    if ((ty = BN_CTX_get(ctx)) == NULL)
        goto err;
    if (EC_POINT_set_affine_coordinates_GFp(key->group, point, x, y, ctx) == 0)
        goto err;
    if (EC_POINT_get_affine_coordinates_GFp(key->group, point, tx, ty, ctx) == 0)
        goto err;
    /*
     * Check if retrieved coordinates match originals: if not values are
     * out of range.
     */
    if (BN_cmp(x, tx) != 0 || BN_cmp(y, ty) != 0) {
        GOSTerr(GOST_F_GOST_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES,
                EC_R_COORDINATES_OUT_OF_RANGE);
        goto err;
    }
    if (GOST_KEY_set_public_key(key, point) != 0)
        goto err;

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

    ok = 1;

err:
    BN_CTX_free(ctx);
    EC_POINT_free(point);
    return ok;
}
Beispiel #3
0
int ec_GFp_simple_make_affine (const EC_GROUP * group, EC_POINT * point, BN_CTX * ctx)
{
    BN_CTX *new_ctx = NULL;

    BIGNUM *x, *y;

    int ret = 0;

    if (point->Z_is_one || EC_POINT_is_at_infinity (group, point))
        return 1;

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

    BN_CTX_start (ctx);
    x = BN_CTX_get (ctx);
    y = BN_CTX_get (ctx);
    if (y == NULL)
        goto err;

    if (!EC_POINT_get_affine_coordinates_GFp (group, point, x, y, ctx))
        goto err;
    if (!EC_POINT_set_affine_coordinates_GFp (group, point, x, y, ctx))
        goto err;
    if (!point->Z_is_one)
    {
        ECerr (EC_F_EC_GFP_SIMPLE_MAKE_AFFINE, ERR_R_INTERNAL_ERROR);
        goto err;
    }

    ret = 1;

  err:
    BN_CTX_end (ctx);
    if (new_ctx != NULL)
        BN_CTX_free (new_ctx);
    return ret;
}
Beispiel #4
0
int ec_GFp_simple_make_affine(const EC_GROUP *group, EC_POINT *point,
                              BN_CTX *ctx) {
  BN_CTX *new_ctx = NULL;
  BIGNUM *x, *y;
  int ret = 0;

  if (point->Z_is_one || EC_POINT_is_at_infinity(group, point)) {
    return 1;
  }

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

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

  if (!EC_POINT_get_affine_coordinates_GFp(group, point, x, y, ctx) ||
      !EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx)) {
    goto err;
  }
  if (!point->Z_is_one) {
    OPENSSL_PUT_ERROR(EC, ec_GFp_simple_make_affine, ERR_R_INTERNAL_ERROR);
    goto err;
  }

  ret = 1;

err:
  BN_CTX_end(ctx);
  if (new_ctx != NULL) {
    BN_CTX_free(new_ctx);
  }
  return ret;
}
Beispiel #5
0
// Get the AlphaCrypt default PEER public Key
EC_POINT * CAlphaCrypt::GetAlphaCryptPublicKey() {
	EC_KEY * lpPublicCurve = NULL;				// Curve that contains the public key
	EC_POINT * pubKey = NULL;					// Public key generated from the 2 coordinates
	const LPSTR XCoordHex = "46668077A4449322CA896BD64901DE333156B6FEAE75ABE5D4922A039B3CD013";
	const LPSTR YCoordHex = "304AB8B3F15F498094F14058A1D1EBE823BEF512D44210CC50BBD94128D2CD05";
	BIGNUM * pBnX = NULL, * pBnY = NULL;
	int iRet = 0;

	// Allocate the 2 points structures
	pBnX = BN_new(); pBnY = BN_new();

	// Get X and Y Coordinate
	BN_hex2bn(&pBnX, XCoordHex);
	BN_hex2bn(&pBnY, YCoordHex);

	// Create the curve that contains the public key 
	lpPublicCurve = EC_KEY_new_by_curve_name(NID_secp256k1);

	// Create the generator 
	pubKey = EC_POINT_new(lpPublicCurve->group);

	// Generate the Public key and verify it
	EC_POINT_set_affine_coordinates_GFp(lpPublicCurve->group, pubKey, pBnX, pBnY, NULL);
	EC_KEY_set_public_key(lpPublicCurve, pubKey);
	iRet = EC_KEY_check_key(lpPublicCurve);

	// Cleanup
	EC_KEY_free(lpPublicCurve);
	BN_free(pBnX); BN_free(pBnY);

	if (iRet)
		return pubKey;
	else 
		EC_POINT_free(pubKey);
	return NULL;
}
Beispiel #6
0
int BFIBE_do_decrypt(BFPublicParameters *mpk,
	const BFCiphertextBlock *in, unsigned char *out, size_t *outlen,
	BFPrivateKeyBlock *sk)
{
	int ret = 0;
	BN_CTX *bn_ctx = NULL;
	EC_GROUP *group = NULL;
	EC_POINT *point = NULL;
	EC_POINT *point1 = NULL;
	BN_GFP2 *theta = NULL;
	BIGNUM *k;
	const EVP_MD *md;
	KDF_FUNC hash_bytes;
	unsigned char rho[EVP_MAX_MD_SIZE * 2];
	size_t size;
	unsigned int len;
	int i;

	if (!mpk || !in || !outlen || !sk) {
		BFIBEerr(BFIBE_F_BFIBE_DO_DECRYPT, ERR_R_PASSED_NULL_PARAMETER);
		return 0;
	}

	if (!out) {
		*outlen = in->w->length;
		return 1;
	}
	if (*outlen < in->w->length) {
		BFIBEerr(BFIBE_F_BFIBE_DO_DECRYPT,
			BFIBE_R_BUFFER_TOO_SMALL);
		return 0;
	}

	/* BN_CTX */
	if (!(bn_ctx = BN_CTX_new())) {
		BFIBEerr(BFIBE_F_BFIBE_DO_DECRYPT, ERR_R_MALLOC_FAILURE);
		goto end;
	}
	BN_CTX_start(bn_ctx);

	/* EC_GROUP */
	if (!(group = EC_GROUP_new_type1curve(mpk->p, mpk->pointP->x,
		mpk->pointP->y, mpk->q, bn_ctx))) {
		BFIBEerr(BFIBE_F_BFIBE_DO_DECRYPT,
			BFIBE_R_INVALID_TYPE1CURVE);
		goto end;
	}

	point = EC_POINT_new(group);
	point1 = EC_POINT_new(group);
	theta = BN_GFP2_new();
	k = BN_CTX_get(bn_ctx);

	if (!point || !point1 || !theta || !k) {
		BFIBEerr(BFIBE_F_BFIBE_DO_DECRYPT, ERR_R_MALLOC_FAILURE);
		goto end;
	}

	/* theta = e(ciphertext->u, sk->privateKey) */
	if (!EC_POINT_set_affine_coordinates_GFp(group, point,
		in->u->x, in->u->y, bn_ctx)) {
		BFIBEerr(BFIBE_F_BFIBE_DO_DECRYPT, ERR_R_EC_LIB);
		goto end;
	}
	if (!EC_POINT_set_affine_coordinates_GFp(group, point1,
		sk->privateKey->x, sk->privateKey->y, bn_ctx)) {
		BFIBEerr(BFIBE_F_BFIBE_DO_DECRYPT, ERR_R_EC_LIB);
		goto end;
	}
	if (!EC_type1curve_tate(group, theta, point, point1, bn_ctx)) {
		BFIBEerr(BFIBE_F_BFIBE_DO_DECRYPT, ERR_R_EC_LIB);
		goto end;
	}

	/* md = mpk->hashfcn */
	if (!(md = EVP_get_digestbyobj(mpk->hashfcn))) {
		BFIBEerr(BFIBE_F_BFIBE_DO_DECRYPT, BFIBE_R_INVALID_BFIBE_HASHFUNC);
		goto end;
	}

	/* rho = Hash(Canoncial(theta)) xor ciphertext->v */
	size = sizeof(rho);
	if (!BN_GFP2_canonical(theta, rho, &size, 0, mpk->p, bn_ctx)) {
		BFIBEerr(BFIBE_F_BFIBE_DO_DECRYPT, ERR_R_EC_LIB);
		goto end;
	}
	len = size;
	if (!EVP_Digest(rho, size, rho, &len, md, NULL)) {
		BFIBEerr(BFIBE_F_BFIBE_DO_DECRYPT, ERR_R_EVP_LIB);
		goto end;
	}
	for (i = 0; i < EVP_MD_size(md); i++) {
		rho[i] ^= in->v->data[i];
	}

	/* function hash_bytes() = kdf(md) */
	if (!(hash_bytes = KDF_get_ibcs(md))) {
		BFIBEerr(BFIBE_F_BFIBE_DO_DECRYPT,
			BFIBE_R_INVALID_BFIBE_HASHFUNC);
		goto end;
	}

	/* out = HashBytes(rho) xor ciphertext->w */
	size = in->w->length;
	if (!hash_bytes(rho, EVP_MD_size(md), out, &size)) {
		BFIBEerr(BFIBE_F_BFIBE_DO_DECRYPT,
			BFIBE_R_KDF_FAILURE);
		goto end;
	}
	for (i = 0; i < in->w->length; i++) {
		out[i] ^= in->w->data[i];
	}

	/* k = HashToRange(rho || Hash(out)) in [0, mpk->q) */
	len = EVP_MD_size(md);
	if (!EVP_Digest(out, in->w->length, rho + EVP_MD_size(md), &len, md, NULL)) {
		BFIBEerr(BFIBE_F_BFIBE_DO_DECRYPT, ERR_R_EVP_LIB);
		goto end;
	}
	if (!BN_hash_to_range(md, &k, rho, EVP_MD_size(md) * 2, mpk->q, bn_ctx)) {
		BFIBEerr(BFIBE_F_BFIBE_DO_DECRYPT, ERR_R_BN_LIB);
		goto end;
	}

	/* Verify that in->u == mpk->pointP * k */
	if (!EC_POINT_mul(group, point, k, NULL, NULL, bn_ctx)) {
		BFIBEerr(BFIBE_F_BFIBE_DO_DECRYPT, ERR_R_EC_LIB);
		goto end;
	}
	if (1 != EC_POINT_cmp_fppoint(group, point, in->u, bn_ctx)) {
		BFIBEerr(BFIBE_F_BFIBE_DO_DECRYPT, BFIBE_R_BFIBE_CIPHERTEXT_FAILURE);
		goto end;
	}

	*outlen = in->w->length;
	ret = 1;

end:
	if (bn_ctx) {
		BN_CTX_end(bn_ctx);
	}
	BN_CTX_free(bn_ctx);
	EC_GROUP_free(group);
	EC_POINT_free(point);
	EC_POINT_free(point1);
	BN_GFP2_free(theta);
	return ret;
}
Beispiel #7
0
static EC_GROUP *ec_group_new_from_data(const ec_list_element curve)
	{
	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;
	int	 seed_len,param_len;
	const EC_METHOD *meth;
	const EC_CURVE_DATA *data;
	const unsigned char *params;

	if ((ctx = BN_CTX_new()) == NULL)
		{
		ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_MALLOC_FAILURE);
		goto err;
		}

	data = curve.data;
	seed_len  = data->seed_len;
	param_len = data->param_len;
	params	  = (const unsigned char *)(data+1);	/* skip header */
	params	 += seed_len;				/* skip seed   */

	if (!(p = BN_bin2bn(params+0*param_len, param_len, NULL))
		|| !(a = BN_bin2bn(params+1*param_len, param_len, NULL))
		|| !(b = BN_bin2bn(params+2*param_len, param_len, NULL)))
		{
		ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB);
		goto err;
		}

	if (curve.meth != 0)
		{
		meth = curve.meth();
		if (((group = EC_GROUP_new(meth)) == NULL) ||
			(!(group->meth->group_set_curve(group, p, a, b, ctx))))
			{
			ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
			goto err;
			}
		}
	else 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;
			}
		}
#ifndef OPENSSL_NO_EC2M
	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;
			}
		}
#endif

	if ((P = EC_POINT_new(group)) == NULL)
		{
		ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
		goto err;
		}

	if (!(x = BN_bin2bn(params+3*param_len, param_len, NULL))
		|| !(y = BN_bin2bn(params+4*param_len, param_len, NULL)))
		{
		ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB);
		goto err;
		}
	if (!EC_POINT_set_affine_coordinates_GFp(group, P, x, y, ctx))
		{
		ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
		goto err;
		}
	if (!(order = BN_bin2bn(params+5*param_len, param_len, NULL))
		|| !BN_set_word(x, (BN_ULONG)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 (seed_len)
		{
		if (!EC_GROUP_set_seed(group, params-seed_len, 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;
	}
void prime_field_tests()
	{	
	BN_CTX *ctx = NULL;
	BIGNUM *p, *a, *b;
	EC_GROUP *group;
	EC_GROUP *P_160 = NULL, *P_192 = NULL, *P_224 = NULL, *P_256 = NULL, *P_384 = NULL, *P_521 = NULL;
	EC_POINT *P, *Q, *R;
	BIGNUM *x, *y, *z;
	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, "17")) ABORT;
	if (!BN_hex2bn(&a, "1")) ABORT;
	if (!BN_hex2bn(&b, "1")) ABORT;
	
	group = EC_GROUP_new(EC_GFp_mont_method()); /* applications should use EC_GROUP_new_curve_GFp
	                                             * so that the library gets to choose the EC_METHOD */
	if (!group) ABORT;

	if (!EC_GROUP_set_curve_GFp(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_GFp(group, p, a, b, ctx)) ABORT;

	fprintf(stdout, "Curve defined by Weierstrass equation\n     y^2 = x^3 + a*x + 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");

	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();
	if (!x || !y || !z) ABORT;

	if (!BN_hex2bn(&x, "D")) ABORT;
	if (!EC_POINT_set_compressed_coordinates_GFp(group, Q, x, 1, ctx)) ABORT;
	if (!EC_POINT_is_on_curve(group, Q, ctx))
		{
		if (!EC_POINT_get_affine_coordinates_GFp(group, Q, x, y, ctx)) ABORT;
		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_GFp(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;

#if 0 /* optional */
		{
			EC_POINT *points[3];
		
			points[0] = R;
			points[1] = Q;
			points[2] = P;
			if (!EC_POINTs_make_affine(group, 2, points, ctx)) ABORT;
		}
#endif

		}
	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;

	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 octect string, compressed form:\n     ");
	for (i = 0; i < len; i++) fprintf(stdout, "%02X", buf[i]);
	
	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 octect string, uncompressed form:\n     ");
	for (i = 0; i < len; i++) fprintf(stdout, "%02X", buf[i]);
	
	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 octect string, hybrid form:\n     ");
	for (i = 0; i < len; i++) fprintf(stdout, "%02X", buf[i]);
	
	if (!EC_POINT_get_Jprojective_coordinates_GFp(group, R, x, y, z, ctx)) ABORT;
	fprintf(stdout, "\nA representation of the inverse of that generator in\nJacobian projective coordinates:\n     X = 0x");
	BN_print_fp(stdout, x);
	fprintf(stdout, ", Y = 0x");
	BN_print_fp(stdout, y);
	fprintf(stdout, ", Z = 0x");
	BN_print_fp(stdout, z);
	fprintf(stdout, "\n");

	if (!EC_POINT_invert(group, P, ctx)) ABORT;
	if (0 != EC_POINT_cmp(group, P, R, ctx)) ABORT;


	/* Curve secp160r1 (Certicom Research SEC 2 Version 1.0, section 2.4.2, 2000)
	 * -- not a NIST curve, but commonly used */
	
	if (!BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF")) ABORT;
	if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) ABORT;
	if (!BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC")) ABORT;
	if (!BN_hex2bn(&b, "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45")) ABORT;
	if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) ABORT;

	if (!BN_hex2bn(&x, "4A96B5688EF573284664698968C38BB913CBFC82")) ABORT;
	if (!BN_hex2bn(&y, "23a628553168947d59dcc912042351377ac5fb32")) ABORT;
	if (!EC_POINT_set_affine_coordinates_GFp(group, P, x, y, ctx)) ABORT;
	if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
	if (!BN_hex2bn(&z, "0100000000000000000001F4C8F927AED3CA752257")) ABORT;
	if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT;

	if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) ABORT;
	fprintf(stdout, "\nSEC2 curve secp160r1 -- Generator:\n     x = 0x");
	BN_print_fp(stdout, x);
	fprintf(stdout, "\n     y = 0x");
	BN_print_fp(stdout, y);
	fprintf(stdout, "\n");
	/* G_y value taken from the standard: */
	if (!BN_hex2bn(&z, "23a628553168947d59dcc912042351377ac5fb32")) ABORT;
	if (0 != BN_cmp(y, z)) ABORT;

	fprintf(stdout, "verify degree ...");
	if (EC_GROUP_get_degree(group) != 160) ABORT;
	fprintf(stdout, " ok\n");
	
	fprintf(stdout, "verify group order ...");
	fflush(stdout);
	if (!EC_GROUP_get_order(group, z, ctx)) ABORT;
	if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT;
	if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
	fprintf(stdout, ".");
	fflush(stdout);
	if (!EC_GROUP_precompute_mult(group, ctx)) ABORT;
	if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT;
	if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
	fprintf(stdout, " ok\n");

	if (!(P_160 = EC_GROUP_new(EC_GROUP_method_of(group)))) ABORT;
	if (!EC_GROUP_copy(P_160, group)) ABORT;


	/* Curve P-192 (FIPS PUB 186-2, App. 6) */
	
	if (!BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF")) ABORT;
	if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) ABORT;
	if (!BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC")) ABORT;
	if (!BN_hex2bn(&b, "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1")) ABORT;
	if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) ABORT;

	if (!BN_hex2bn(&x, "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012")) ABORT;
	if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 1, ctx)) ABORT;
	if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
	if (!BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831")) ABORT;
	if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT;

	if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) ABORT;
	fprintf(stdout, "\nNIST curve P-192 -- Generator:\n     x = 0x");
	BN_print_fp(stdout, x);
	fprintf(stdout, "\n     y = 0x");
	BN_print_fp(stdout, y);
	fprintf(stdout, "\n");
	/* G_y value taken from the standard: */
	if (!BN_hex2bn(&z, "07192B95FFC8DA78631011ED6B24CDD573F977A11E794811")) ABORT;
	if (0 != BN_cmp(y, z)) ABORT;

	fprintf(stdout, "verify degree ...");
	if (EC_GROUP_get_degree(group) != 192) ABORT;
	fprintf(stdout, " ok\n");
	
	fprintf(stdout, "verify group order ...");
	fflush(stdout);
	if (!EC_GROUP_get_order(group, z, ctx)) ABORT;
	if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT;
	if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
	fprintf(stdout, ".");
	fflush(stdout);
#if 0
	if (!EC_GROUP_precompute_mult(group, ctx)) ABORT;
#endif
	if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT;
	if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
	fprintf(stdout, " ok\n");

	if (!(P_192 = EC_GROUP_new(EC_GROUP_method_of(group)))) ABORT;
	if (!EC_GROUP_copy(P_192, group)) ABORT;


	/* Curve P-224 (FIPS PUB 186-2, App. 6) */
	
	if (!BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001")) ABORT;
	if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) ABORT;
	if (!BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE")) ABORT;
	if (!BN_hex2bn(&b, "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4")) ABORT;
	if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) ABORT;

	if (!BN_hex2bn(&x, "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21")) ABORT;
	if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 0, ctx)) ABORT;
	if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
	if (!BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D")) ABORT;
	if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT;

	if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) ABORT;
	fprintf(stdout, "\nNIST curve P-224 -- Generator:\n     x = 0x");
	BN_print_fp(stdout, x);
	fprintf(stdout, "\n     y = 0x");
	BN_print_fp(stdout, y);
	fprintf(stdout, "\n");
	/* G_y value taken from the standard: */
	if (!BN_hex2bn(&z, "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34")) ABORT;
	if (0 != BN_cmp(y, z)) ABORT;
	
	fprintf(stdout, "verify degree ...");
	if (EC_GROUP_get_degree(group) != 224) ABORT;
	fprintf(stdout, " ok\n");
	
	fprintf(stdout, "verify group order ...");
	fflush(stdout);
	if (!EC_GROUP_get_order(group, z, ctx)) ABORT;
	if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT;
	if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
	fprintf(stdout, ".");
	fflush(stdout);
#if 0
	if (!EC_GROUP_precompute_mult(group, ctx)) ABORT;
#endif
	if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT;
	if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
	fprintf(stdout, " ok\n");

	if (!(P_224 = EC_GROUP_new(EC_GROUP_method_of(group)))) ABORT;
	if (!EC_GROUP_copy(P_224, group)) ABORT;


	/* Curve P-256 (FIPS PUB 186-2, App. 6) */
	
	if (!BN_hex2bn(&p, "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF")) ABORT;
	if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) ABORT;
	if (!BN_hex2bn(&a, "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC")) ABORT;
	if (!BN_hex2bn(&b, "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B")) ABORT;
	if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) ABORT;

	if (!BN_hex2bn(&x, "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296")) ABORT;
	if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 1, ctx)) ABORT;
	if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
	if (!BN_hex2bn(&z, "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E"
		"84F3B9CAC2FC632551")) ABORT;
	if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT;

	if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) ABORT;
	fprintf(stdout, "\nNIST curve P-256 -- Generator:\n     x = 0x");
	BN_print_fp(stdout, x);
	fprintf(stdout, "\n     y = 0x");
	BN_print_fp(stdout, y);
	fprintf(stdout, "\n");
	/* G_y value taken from the standard: */
	if (!BN_hex2bn(&z, "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5")) ABORT;
	if (0 != BN_cmp(y, z)) ABORT;
	
	fprintf(stdout, "verify degree ...");
	if (EC_GROUP_get_degree(group) != 256) ABORT;
	fprintf(stdout, " ok\n");
	
	fprintf(stdout, "verify group order ...");
	fflush(stdout);
	if (!EC_GROUP_get_order(group, z, ctx)) ABORT;
	if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT;
	if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
	fprintf(stdout, ".");
	fflush(stdout);
#if 0
	if (!EC_GROUP_precompute_mult(group, ctx)) ABORT;
#endif
	if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT;
	if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
	fprintf(stdout, " ok\n");

	if (!(P_256 = EC_GROUP_new(EC_GROUP_method_of(group)))) ABORT;
	if (!EC_GROUP_copy(P_256, group)) ABORT;


	/* Curve P-384 (FIPS PUB 186-2, App. 6) */
	
	if (!BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
		"FFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF")) ABORT;
	if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) ABORT;
	if (!BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
		"FFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC")) ABORT;
	if (!BN_hex2bn(&b, "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141"
		"120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF")) ABORT;
	if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) ABORT;

	if (!BN_hex2bn(&x, "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B"
		"9859F741E082542A385502F25DBF55296C3A545E3872760AB7")) ABORT;
	if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 1, ctx)) ABORT;
	if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
	if (!BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
		"FFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973")) ABORT;
	if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT;

	if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) ABORT;
	fprintf(stdout, "\nNIST curve P-384 -- Generator:\n     x = 0x");
	BN_print_fp(stdout, x);
	fprintf(stdout, "\n     y = 0x");
	BN_print_fp(stdout, y);
	fprintf(stdout, "\n");
	/* G_y value taken from the standard: */
	if (!BN_hex2bn(&z, "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A14"
		"7CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F")) ABORT;
	if (0 != BN_cmp(y, z)) ABORT;
	
	fprintf(stdout, "verify degree ...");
	if (EC_GROUP_get_degree(group) != 384) ABORT;
	fprintf(stdout, " ok\n");
	
	fprintf(stdout, "verify group order ...");
	fflush(stdout);
	if (!EC_GROUP_get_order(group, z, ctx)) ABORT;
	if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT;
	if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
	fprintf(stdout, ".");
	fflush(stdout);
#if 0
	if (!EC_GROUP_precompute_mult(group, ctx)) ABORT;
#endif
	if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT;
	if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
	fprintf(stdout, " ok\n");

	if (!(P_384 = EC_GROUP_new(EC_GROUP_method_of(group)))) ABORT;
	if (!EC_GROUP_copy(P_384, group)) ABORT;


	/* Curve P-521 (FIPS PUB 186-2, App. 6) */
	
	if (!BN_hex2bn(&p, "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
		"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
		"FFFFFFFFFFFFFFFFFFFFFFFFFFFF")) ABORT;
	if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) ABORT;
	if (!BN_hex2bn(&a, "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
		"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
		"FFFFFFFFFFFFFFFFFFFFFFFFFFFC")) ABORT;
	if (!BN_hex2bn(&b, "051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B"
		"315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573"
		"DF883D2C34F1EF451FD46B503F00")) ABORT;
	if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) ABORT;

	if (!BN_hex2bn(&x, "C6858E06B70404E9CD9E3ECB662395B4429C648139053F"
		"B521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B"
		"3C1856A429BF97E7E31C2E5BD66")) ABORT;
	if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 0, ctx)) ABORT;
	if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
	if (!BN_hex2bn(&z, "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
		"FFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5"
		"C9B8899C47AEBB6FB71E91386409")) ABORT;
	if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT;

	if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) ABORT;
	fprintf(stdout, "\nNIST curve P-521 -- Generator:\n     x = 0x");
	BN_print_fp(stdout, x);
	fprintf(stdout, "\n     y = 0x");
	BN_print_fp(stdout, y);
	fprintf(stdout, "\n");
	/* G_y value taken from the standard: */
	if (!BN_hex2bn(&z, "11839296A789A3BC0045C8A5FB42C7D1BD998F54449579"
		"B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C"
		"7086A272C24088BE94769FD16650")) ABORT;
	if (0 != BN_cmp(y, z)) ABORT;
	
	fprintf(stdout, "verify degree ...");
	if (EC_GROUP_get_degree(group) != 521) ABORT;
	fprintf(stdout, " ok\n");
	
	fprintf(stdout, "verify group order ...");
	fflush(stdout);
	if (!EC_GROUP_get_order(group, z, ctx)) ABORT;
	if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT;
	if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
	fprintf(stdout, ".");
	fflush(stdout);
#if 0
	if (!EC_GROUP_precompute_mult(group, ctx)) ABORT;
#endif
	if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT;
	if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
	fprintf(stdout, " ok\n");

	if (!(P_521 = EC_GROUP_new(EC_GROUP_method_of(group)))) ABORT;
	if (!EC_GROUP_copy(P_521, group)) ABORT;


	/* 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(P_160, TIMING_BASE_PT, ctx);
	timings(P_160, TIMING_RAND_PT, ctx);
	timings(P_160, TIMING_SIMUL, ctx);
	timings(P_192, TIMING_BASE_PT, ctx);
	timings(P_192, TIMING_RAND_PT, ctx);
	timings(P_192, TIMING_SIMUL, ctx);
	timings(P_224, TIMING_BASE_PT, ctx);
	timings(P_224, TIMING_RAND_PT, ctx);
	timings(P_224, TIMING_SIMUL, ctx);
	timings(P_256, TIMING_BASE_PT, ctx);
	timings(P_256, TIMING_RAND_PT, ctx);
	timings(P_256, TIMING_SIMUL, ctx);
	timings(P_384, TIMING_BASE_PT, ctx);
	timings(P_384, TIMING_RAND_PT, ctx);
	timings(P_384, TIMING_SIMUL, ctx);
	timings(P_521, TIMING_BASE_PT, ctx);
	timings(P_521, TIMING_RAND_PT, ctx);
	timings(P_521, 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);

	if (P_160) EC_GROUP_free(P_160);
	if (P_192) EC_GROUP_free(P_192);
	if (P_224) EC_GROUP_free(P_224);
	if (P_256) EC_GROUP_free(P_256);
	if (P_384) EC_GROUP_free(P_384);
	if (P_521) EC_GROUP_free(P_521);

	}
Beispiel #9
0
/*
 * r = rand(), |r| = hashlen
 * k = HashToRange(r||Hash(m), q), k in [0, q-1]
 * U = [k]P in E/F_p
 * Q = HashToPoint(ID) in E/F_p
 * v = Hash(e(Ppub, Q)^k) xor r, |v| == hashlen
 * w = HashBytes(r) xor m
 */
BFCiphertextBlock *BFIBE_do_encrypt(BFPublicParameters *mpk,
	const unsigned char *in, size_t inlen,
	const char *id, size_t idlen)
{
	int e = 1;
	BFCiphertextBlock *ret = NULL;
	BN_CTX *bn_ctx = NULL;
	EC_GROUP *group = NULL;
	EC_POINT *Ppub = NULL;
	EC_POINT *point = NULL;
	BN_GFP2 *theta = NULL;
	BIGNUM *k;
	const EVP_MD *md;
	KDF_FUNC hash_bytes;
	unsigned char rho[EVP_MAX_MD_SIZE * 2];
	unsigned char buf[EVP_MAX_MD_SIZE];
	unsigned int len;
	size_t size;
	int i;

	if (!mpk || !in || inlen <= 0 || !id || idlen <= 0) {
		BFIBEerr(BFIBE_F_BFIBE_DO_ENCRYPT, ERR_R_PASSED_NULL_PARAMETER);
		return NULL;
	}

	/* BN_CTX */
	if (!(bn_ctx = BN_CTX_new())) {
		BFIBEerr(BFIBE_F_BFIBE_DO_ENCRYPT, ERR_R_MALLOC_FAILURE);
		goto end;
	}
	BN_CTX_start(bn_ctx);

	/* EC_GROUP */
	if (!(group = EC_GROUP_new_type1curve(mpk->p, mpk->pointP->x,
		mpk->pointP->y, mpk->q, bn_ctx))) {
		BFIBEerr(BFIBE_F_BFIBE_DO_ENCRYPT, BFIBE_R_PARSE_MPK_FAILURE);
		goto end;
	}

	ret = BFCiphertextBlock_new();
	Ppub = EC_POINT_new(group);
	point = EC_POINT_new(group);
	theta = BN_GFP2_new();
	k = BN_CTX_get(bn_ctx);

	if (!ret || !point || !Ppub || !k || !theta) {
		BFIBEerr(BFIBE_F_BFIBE_DO_ENCRYPT, ERR_R_MALLOC_FAILURE);
		goto end;
	}


	/* get kdf from mpk->hashfcn */
	if (!(md = EVP_get_digestbyobj(mpk->hashfcn))) {
		BFIBEerr(BFIBE_F_BFIBE_DO_ENCRYPT, BFIBE_R_INVALID_BFIBE_HASHFUNC);
		goto end;
	}

	if (!(hash_bytes = KDF_get_ibcs(md))) {
		BFIBEerr(BFIBE_F_BFIBE_DO_ENCRYPT,
			BFIBE_R_INVALID_BFIBE_HASHFUNC);
		goto end;
	}

	/* ret->version */
	ret->version = BFIBE_VERSION;

	/* rho = Rand(hashlen) */
	if (!RAND_bytes(rho, EVP_MD_size(md))) {
		BFIBEerr(BFIBE_F_BFIBE_DO_ENCRYPT, BFIBE_R_RAND_FAILURE);
		goto end;
	}

	/* k = HashToRange(rho||Hash(in), q) in [0, q - 1] */
	len = EVP_MD_size(md);
	if (!EVP_Digest(in, inlen, rho + EVP_MD_size(md), &len, md, NULL)) {
		BFIBEerr(BFIBE_F_BFIBE_DO_ENCRYPT, ERR_R_EVP_LIB);
		goto end;
	}
	if (!BN_hash_to_range(md, &k, rho, EVP_MD_size(md) * 2, mpk->q, bn_ctx)) {
		BFIBEerr(BFIBE_F_BFIBE_DO_ENCRYPT, ERR_R_BN_LIB);
		goto end;
	}

	/* ret->u = mpk->pointP * k in E/F_p, mpk->pointP is the generator */
	if (!EC_POINT_mul(group, point, k, NULL, NULL, bn_ctx)) {
		BFIBEerr(BFIBE_F_BFIBE_DO_ENCRYPT, ERR_R_EC_LIB);
		goto end;
	}
	if (!EC_POINT_get_affine_coordinates_GFp(group, point,
		ret->u->x, ret->u->y, bn_ctx)) {
		BFIBEerr(BFIBE_F_BFIBE_DO_ENCRYPT, ERR_R_EC_LIB);
		goto end;
	}

	/* theta = e(mpk->pointPpub, HashToPoint(ID)) */
	if (!EC_POINT_set_affine_coordinates_GFp(group, Ppub,
		mpk->pointPpub->x, mpk->pointPpub->y, bn_ctx)) {
		BFIBEerr(BFIBE_F_BFIBE_DO_ENCRYPT, ERR_R_EC_LIB);
		goto end;
	}
	if (!EC_POINT_hash2point(group, md, id, idlen, point, bn_ctx)) {
		BFIBEerr(BFIBE_F_BFIBE_DO_ENCRYPT, ERR_R_EC_LIB);
		goto end;
	}
	if (!EC_type1curve_tate(group, theta, Ppub, point, bn_ctx)) {
		BFIBEerr(BFIBE_F_BFIBE_DO_ENCRYPT, ERR_R_EC_LIB);
		goto end;
	}

	/* theta = theta^k */
	if (!BN_GFP2_exp(theta, theta, k, mpk->p, bn_ctx)) {
		BFIBEerr(BFIBE_F_BFIBE_DO_ENCRYPT, ERR_R_EC_LIB);
		goto end;
	}

	/* ret->v = Hash(theta) xor rho */
	size = sizeof(buf);
	if (!BN_GFP2_canonical(theta, buf, &size, 0, mpk->p, bn_ctx)) {
		BFIBEerr(BFIBE_F_BFIBE_DO_ENCRYPT, ERR_R_BN_LIB);
		goto end;
	}
	len = sizeof(buf);
	if (!EVP_Digest(buf, size, buf, &len, md, NULL)) {
		BFIBEerr(BFIBE_F_BFIBE_DO_ENCRYPT, ERR_R_EVP_LIB);
		goto end;
	}
	for (i = 0; i < EVP_MD_size(md); i++) {
		buf[i] ^= rho[i];
	}
	if (!ASN1_OCTET_STRING_set(ret->v, buf, EVP_MD_size(md))) {
		BFIBEerr(BFIBE_F_BFIBE_DO_ENCRYPT, ERR_R_ASN1_LIB);
		goto end;
	}

	/*  ret->w = HashBytes(rho) xor m */
	if (!ASN1_OCTET_STRING_set(ret->w, NULL, inlen)) {
		BFIBEerr(BFIBE_F_BFIBE_DO_ENCRYPT, ERR_R_MALLOC_FAILURE);
		goto end;
	}
	size = inlen;
	if (!hash_bytes(rho, EVP_MD_size(md), ret->w->data, &size)) {
		BFIBEerr(BFIBE_F_BFIBE_DO_ENCRYPT,
			BFIBE_R_HASH_BYTES_FAILURE);
		goto end;
	}
	for (i = 0; i < inlen; i++) {
		ret->w->data[i] ^= in[i];
	}

	e = 0;

end:
	if (e && ret) {
		BFCiphertextBlock_free(ret);
		ret = NULL;
	}
	if (bn_ctx) {
		BN_CTX_end(bn_ctx);
	}
	BN_CTX_free(bn_ctx);
	EC_GROUP_free(group);
	EC_POINT_free(Ppub);
	EC_POINT_free(point);
	BN_GFP2_free(theta);
	return ret;
}
static int ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
                                   const uint8_t *buf, size_t len,
                                   BN_CTX *ctx) {
  point_conversion_form_t form;
  int y_bit;
  BN_CTX *new_ctx = NULL;
  BIGNUM *x, *y;
  size_t field_len, enc_len;
  int ret = 0;

  if (len == 0) {
    OPENSSL_PUT_ERROR(EC, ec_GFp_simple_oct2point, EC_R_BUFFER_TOO_SMALL);
    return 0;
  }
  form = buf[0];
  y_bit = form & 1;
  form = form & ~1U;
  if ((form != 0) && (form != POINT_CONVERSION_COMPRESSED) &&
      (form != POINT_CONVERSION_UNCOMPRESSED) &&
      (form != POINT_CONVERSION_HYBRID)) {
    OPENSSL_PUT_ERROR(EC, ec_GFp_simple_oct2point, EC_R_INVALID_ENCODING);
    return 0;
  }
  if ((form == 0 || form == POINT_CONVERSION_UNCOMPRESSED) && y_bit) {
    OPENSSL_PUT_ERROR(EC, ec_GFp_simple_oct2point, EC_R_INVALID_ENCODING);
    return 0;
  }

  if (form == 0) {
    if (len != 1) {
      OPENSSL_PUT_ERROR(EC, ec_GFp_simple_oct2point, EC_R_INVALID_ENCODING);
      return 0;
    }

    return EC_POINT_set_to_infinity(group, point);
  }

  field_len = BN_num_bytes(&group->field);
  enc_len =
      (form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2 * field_len;

  if (len != enc_len) {
    OPENSSL_PUT_ERROR(EC, ec_GFp_simple_oct2point, EC_R_INVALID_ENCODING);
    return 0;
  }

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

  BN_CTX_start(ctx);
  x = BN_CTX_get(ctx);
  y = BN_CTX_get(ctx);
  if (y == NULL)
    goto err;

  if (!BN_bin2bn(buf + 1, field_len, x))
    goto err;
  if (BN_ucmp(x, &group->field) >= 0) {
    OPENSSL_PUT_ERROR(EC, ec_GFp_simple_oct2point, EC_R_INVALID_ENCODING);
    goto err;
  }

  if (form == POINT_CONVERSION_COMPRESSED) {
    if (!EC_POINT_set_compressed_coordinates_GFp(group, point, x, y_bit, ctx))
      goto err;
  } else {
    if (!BN_bin2bn(buf + 1 + field_len, field_len, y))
      goto err;
    if (BN_ucmp(y, &group->field) >= 0) {
      OPENSSL_PUT_ERROR(EC, ec_GFp_simple_oct2point, EC_R_INVALID_ENCODING);
      goto err;
    }
    if (form == POINT_CONVERSION_HYBRID) {
      if (y_bit != BN_is_odd(y)) {
        OPENSSL_PUT_ERROR(EC, ec_GFp_simple_oct2point, EC_R_INVALID_ENCODING);
        goto err;
      }
    }

    if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx))
      goto err;
  }

  if (!EC_POINT_is_on_curve(group, point, ctx)) /* test required by X9.62 */
  {
    OPENSSL_PUT_ERROR(EC, ec_GFp_simple_oct2point, EC_R_POINT_IS_NOT_ON_CURVE);
    goto err;
  }

  ret = 1;

err:
  BN_CTX_end(ctx);
  if (new_ctx != NULL)
    BN_CTX_free(new_ctx);
  return ret;
}
Beispiel #11
0
int
ecdh_im_compute_key(PACE_CTX * ctx, const BUF_MEM * s, const BUF_MEM * in,
        BN_CTX *bn_ctx)
{
    int ret = 0;
    BUF_MEM * x_mem = NULL;
    BIGNUM * a = NULL, *b = NULL, *p = NULL;
    BIGNUM * x = NULL, *y = NULL, *v = NULL, *u = NULL;
    BIGNUM * tmp = NULL, *tmp2 = NULL, *bn_inv = NULL;
    BIGNUM * two = NULL, *three = NULL, *four = NULL, *six = NULL;
    BIGNUM * twentyseven = NULL;
    EC_KEY *static_key = NULL, *ephemeral_key = NULL;
    EC_POINT *g = NULL;

    BN_CTX_start(bn_ctx);

    check((ctx && ctx->static_key && s && ctx->ka_ctx), "Invalid arguments"); 

    static_key = EVP_PKEY_get1_EC_KEY(ctx->static_key);
    if (!static_key)
        goto err;

    /* Setup all the variables*/
    a = BN_CTX_get(bn_ctx);
    b = BN_CTX_get(bn_ctx);
    p = BN_CTX_get(bn_ctx);
    x = BN_CTX_get(bn_ctx);
    y = BN_CTX_get(bn_ctx);
    v = BN_CTX_get(bn_ctx);
    two = BN_CTX_get(bn_ctx);
    three = BN_CTX_get(bn_ctx);
    four = BN_CTX_get(bn_ctx);
    six = BN_CTX_get(bn_ctx);
    twentyseven = BN_CTX_get(bn_ctx);
    tmp = BN_CTX_get(bn_ctx);
    tmp2 = BN_CTX_get(bn_ctx);
    bn_inv = BN_CTX_get(bn_ctx);
    if (!bn_inv)
        goto err;

    /* Encrypt the Nonce using the symmetric key in */
    x_mem = cipher_no_pad(ctx->ka_ctx, NULL, in, s, 1);
    if (!x_mem)
        goto err;

    /* Fetch the curve parameters */
    if (!EC_GROUP_get_curve_GFp(EC_KEY_get0_group(static_key), p, a, b, bn_ctx))
        goto err;

    /* Assign constants */
    if (    !BN_set_word(two,2)||
            !BN_set_word(three,3)||
            !BN_set_word(four,4)||
            !BN_set_word(six,6)||
            !BN_set_word(twentyseven,27)
            ) goto err;

    /* Check prerequisites for curve parameters */
    check(
            /* p > 3;*/
           (BN_cmp(p, three) == 1) &&
           /* p mod 3 = 2; (p has the form p=q^n, q prime) */
           BN_nnmod(tmp, p, three, bn_ctx) &&
           (BN_cmp(tmp, two) == 0),
        "Unsuited curve");

    /* Convert encrypted nonce to BIGNUM */
    u = BN_bin2bn((unsigned char *) x_mem->data, x_mem->length, u);
    if (!u)
        goto err;

    if ( /* v = (3a - u^4) / 6u mod p */
            !BN_mod_mul(tmp, three, a, p, bn_ctx) ||
            !BN_mod_exp(tmp2, u, four, p, bn_ctx) ||
            !BN_mod_sub(v, tmp, tmp2, p, bn_ctx) ||
            !BN_mod_mul(tmp, u, six, p, bn_ctx) ||
            /* For division within a galois field we need to compute
             * the multiplicative inverse of a number */
            !BN_mod_inverse(bn_inv, tmp, p, bn_ctx) ||
            !BN_mod_mul(v, v, bn_inv, p, bn_ctx) ||

            /* x = (v^2 - b - ((u^6)/27)) */
            !BN_mod_sqr(tmp, v, p, bn_ctx) ||
            !BN_mod_sub(tmp2, tmp, b, p, bn_ctx) ||
            !BN_mod_exp(tmp, u, six, p, bn_ctx) ||
            !BN_mod_inverse(bn_inv, twentyseven, p, bn_ctx) ||
            !BN_mod_mul(tmp, tmp, bn_inv, p, bn_ctx) ||
            !BN_mod_sub(x, tmp2, tmp, p, bn_ctx) ||

            /* x -> x^(1/3) = x^((2p^n -1)/3) */
            !BN_mul(tmp, two, p, bn_ctx) ||
            !BN_sub(tmp, tmp, BN_value_one()) ||

            /* Division is defined, because p^n = 2 mod 3 */
            !BN_div(tmp, y, tmp, three, bn_ctx) ||
            !BN_mod_exp(tmp2, x, tmp, p, bn_ctx) ||
            !BN_copy(x, tmp2) ||

            /* x += (u^2)/3 */
            !BN_mod_sqr(tmp, u, p, bn_ctx) ||
            !BN_mod_inverse(bn_inv, three, p, bn_ctx) ||
            !BN_mod_mul(tmp2, tmp, bn_inv, p, bn_ctx) ||
            !BN_mod_add(tmp, x, tmp2, p, bn_ctx) ||
            !BN_copy(x, tmp) ||

            /* y = ux + v */
            !BN_mod_mul(y, u, x, p, bn_ctx) ||
            !BN_mod_add(tmp, y, v, p, bn_ctx) ||
            !BN_copy(y, tmp)
            )
        goto err;

    /* Initialize ephemeral parameters with parameters from the static key */
    ephemeral_key = EC_KEY_dup(static_key);
    if (!ephemeral_key)
        goto err;
    EVP_PKEY_set1_EC_KEY(ctx->ka_ctx->key, ephemeral_key);

    /* configure the new EC_KEY */
    g = EC_POINT_new(EC_KEY_get0_group(ephemeral_key));
    if (!g)
        goto err;
    if (!EC_POINT_set_affine_coordinates_GFp(EC_KEY_get0_group(ephemeral_key), g,
            x, y, bn_ctx))
        goto err;

    ret = 1;

err:
    if (x_mem)
        BUF_MEM_free(x_mem);
    if (u)
        BN_free(u);
    BN_CTX_end(bn_ctx);
    if (g)
        EC_POINT_clear_free(g);
    /* Decrement reference count, keys are still available via PACE_CTX */
    if (static_key)
        EC_KEY_free(static_key);
    if (ephemeral_key)
        EC_KEY_free(ephemeral_key);

    return ret;
}
Beispiel #12
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;
	int seed_len = 0;
	int param_len = 0;
	const unsigned char *params = NULL;

	ctx = BN_CTX_new();
	if (ctx == NULL) {
		ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_MALLOC_FAILURE);
		goto err;
	}

	seed_len = data->seed_len;
	param_len = data->param_len;
	params = (const unsigned char *)(data+1); /* skip header */
	params += seed_len; /* skip seed   */

	if (
		   !(p = BN_bin2bn(params+0*param_len, param_len, NULL))
		|| !(a = BN_bin2bn(params+1*param_len, param_len, NULL))
		|| !(b = BN_bin2bn(params+2*param_len, param_len, NULL))
	) {
		ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB);
		goto err;
	}

	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;
	}

	if ((P = EC_POINT_new(group)) == NULL) {
		ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
	goto err;
	}

	if (
		   !(x = BN_bin2bn(params+3*param_len, param_len, NULL))
		|| !(y = BN_bin2bn(params+4*param_len, param_len, NULL))
	) {
		ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB);
		goto err;
	}

	if (!EC_POINT_set_affine_coordinates_GFp(group, P, x, y, ctx)) {
		ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
		goto err;
	}

	if (
		!(order = BN_bin2bn(params+5*param_len, param_len, NULL))
		|| !BN_set_word(x, (BN_ULONG)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 (seed_len) {
		if (!EC_GROUP_set_seed(group, params-seed_len, 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;
}
Beispiel #13
0
int process_peer_commit(REQUEST *request, pwd_session_t *session, uint8_t *in, size_t in_len, BN_CTX *bn_ctx)
{
	uint8_t		*ptr;
	size_t		data_len;
	BIGNUM		*x = NULL, *y = NULL, *cofactor = NULL;
	EC_POINT	*K = NULL, *point = NULL;
	int		ret = 1;

	MEM(session->peer_scalar = BN_new());
	MEM(session->k = BN_new());
	MEM(session->peer_element = EC_POINT_new(session->group));
	MEM(point = EC_POINT_new(session->group));
	MEM(K = EC_POINT_new(session->group));

	MEM(cofactor = BN_new());
	MEM(x = BN_new());
	MEM(y = BN_new());

	if (!EC_GROUP_get_cofactor(session->group, cofactor, NULL)) {
		REDEBUG("Unable to get group co-factor");
		goto finish;
	}

	/* element, x then y, followed by scalar */
	ptr = (uint8_t *)in;
	data_len = BN_num_bytes(session->prime);

	/*
	 *	Did the peer send enough data?
	 */
	if (in_len < (2 * data_len + BN_num_bytes(session->order))) {
		REDEBUG("Invalid commit packet");
		goto finish;
	}

	BN_bin2bn(ptr, data_len, x);
	ptr += data_len;
	BN_bin2bn(ptr, data_len, y);
	ptr += data_len;

	data_len = BN_num_bytes(session->order);
	BN_bin2bn(ptr, data_len, session->peer_scalar);

	/* validate received scalar */
	if (BN_is_zero(session->peer_scalar) ||
	    BN_is_one(session->peer_scalar) ||
	    BN_cmp(session->peer_scalar, session->order) >= 0) {
		REDEBUG("Peer's scalar is not within the allowed range");
		goto finish;
	}

	if (!EC_POINT_set_affine_coordinates_GFp(session->group, session->peer_element, x, y, bn_ctx)) {
		REDEBUG("Unable to get coordinates of peer's element");
		goto finish;
	}

	/* validate received element */
	if (!EC_POINT_is_on_curve(session->group, session->peer_element, bn_ctx) ||
	    EC_POINT_is_at_infinity(session->group, session->peer_element)) {
		REDEBUG("Peer's element is not a point on the elliptic curve");
		goto finish;
	}

	/* check to ensure peer's element is not in a small sub-group */
	if (BN_cmp(cofactor, BN_value_one())) {
		if (!EC_POINT_mul(session->group, point, NULL, session->peer_element, cofactor, NULL)) {
			REDEBUG("Unable to multiply element by co-factor");
			goto finish;
		}

		if (EC_POINT_is_at_infinity(session->group, point)) {
			REDEBUG("Peer's element is in small sub-group");
			goto finish;
		}
	}

	/* detect reflection attacks */
	if (BN_cmp(session->peer_scalar, session->my_scalar) == 0 ||
	    EC_POINT_cmp(session->group, session->peer_element, session->my_element, bn_ctx) == 0) {
		REDEBUG("Reflection attack detected");
		goto finish;
	}

	/* compute the shared key, k */
	if ((!EC_POINT_mul(session->group, K, NULL, session->pwe, session->peer_scalar, bn_ctx)) ||
	    (!EC_POINT_add(session->group, K, K, session->peer_element, bn_ctx)) ||
	    (!EC_POINT_mul(session->group, K, NULL, K, session->private_value, bn_ctx))) {
		REDEBUG("Unable to compute shared key, k");
		goto finish;
	}

	/* ensure that the shared key isn't in a small sub-group */
	if (BN_cmp(cofactor, BN_value_one())) {
		if (!EC_POINT_mul(session->group, K, NULL, K, cofactor, NULL)) {
			REDEBUG("Unable to multiply k by co-factor");
			goto finish;
		}
	}

	/*
	 * This check is strictly speaking just for the case above where
	 * co-factor > 1 but it was suggested that even though this is probably
	 * never going to happen it is a simple and safe check "just to be
	 * sure" so let's be safe.
	 */
	if (EC_POINT_is_at_infinity(session->group, K)) {
		REDEBUG("K is point-at-infinity");
		goto finish;
	}

	if (!EC_POINT_get_affine_coordinates_GFp(session->group, K, session->k, NULL, bn_ctx)) {
		REDEBUG("Unable to get shared secret from K");
		goto finish;
	}
	ret = 0;

finish:
	EC_POINT_clear_free(K);
	EC_POINT_clear_free(point);
	BN_clear_free(cofactor);
	BN_clear_free(x);
	BN_clear_free(y);

	return ret;
}
Beispiel #14
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;
}
Beispiel #15
0
static CK_RV gostr3410_verify_data(const unsigned char *pubkey, int pubkey_len,
		const unsigned char *params, int params_len,
		unsigned char *data, int data_len,
		unsigned char *signat, int signat_len)
{
	EVP_PKEY *pkey;
	EVP_PKEY_CTX *pkey_ctx;
	EC_POINT *P;
	BIGNUM *X, *Y;
	ASN1_OCTET_STRING *octet;
	const EC_GROUP *group = NULL;
	char paramset[2] = "A";
	int r = -1, ret_vrf = 0;

	pkey = EVP_PKEY_new();
	if (!pkey)
		return CKR_HOST_MEMORY;
	r = EVP_PKEY_set_type(pkey, NID_id_GostR3410_2001);
	if (r == 1) {
		pkey_ctx = EVP_PKEY_CTX_new(pkey, NULL);
		if (!pkey_ctx) {
			EVP_PKEY_free(pkey);
			return CKR_HOST_MEMORY;
		}
		/* FIXME: fully check params[] */
		if (params_len > 0 && params[params_len - 1] >= 1 &&
				params[params_len - 1] <= 3) {
			paramset[0] += params[params_len - 1] - 1;
			r = EVP_PKEY_CTX_ctrl_str(pkey_ctx, "paramset", paramset);
		}
		else
			r = -1;
		if (r == 1)
			r = EVP_PKEY_paramgen_init(pkey_ctx);
		if (r == 1)
			r = EVP_PKEY_paramgen(pkey_ctx, &pkey);
		if (r == 1 && EVP_PKEY_get0(pkey) != NULL)
			group = EC_KEY_get0_group(EVP_PKEY_get0(pkey));
		r = -1;
		if (group)
			octet = d2i_ASN1_OCTET_STRING(NULL, &pubkey, (long)pubkey_len);
		if (group && octet) {
			reverse(octet->data, octet->length);
			Y = BN_bin2bn(octet->data, octet->length / 2, NULL);
			X = BN_bin2bn((const unsigned char*)octet->data +
					octet->length / 2, octet->length / 2, NULL);
			ASN1_OCTET_STRING_free(octet);
			P = EC_POINT_new(group);
			if (P && X && Y)
				r = EC_POINT_set_affine_coordinates_GFp(group,
						P, X, Y, NULL);
			BN_free(X);
			BN_free(Y);
			if (r == 1 && EVP_PKEY_get0(pkey) && P)
				r = EC_KEY_set_public_key(EVP_PKEY_get0(pkey), P);
			EC_POINT_free(P);
		}
		if (r == 1) {
			r = EVP_PKEY_verify_init(pkey_ctx);
			reverse(data, data_len);
			if (r == 1)
				ret_vrf = EVP_PKEY_verify(pkey_ctx, signat, signat_len,
						data, data_len);
		}
	}
	EVP_PKEY_CTX_free(pkey_ctx);
	EVP_PKEY_free(pkey);
	if (r != 1)
		return CKR_GENERAL_ERROR;
	return ret_vrf == 1 ? CKR_OK : CKR_SIGNATURE_INVALID;
}
Beispiel #16
0
/*
 * Fills EC_KEY structure hidden in the app_data field of DSA structure
 * with parameter information, extracted from parameter array in
 * params.c file.
 *
 * Also fils DSA->q field with copy of EC_GROUP order field to make
 * DSA_size function work
 */
int fill_GOST2001_params(EC_KEY *eckey, int nid)
{
    R3410_2001_params *params = R3410_2001_paramset;
    EC_GROUP *grp = NULL;
    BIGNUM *p = NULL, *q = NULL, *a = NULL, *b = NULL, *x = NULL, *y = NULL;
    EC_POINT *P = NULL;
    BN_CTX *ctx = BN_CTX_new();
    int ok = 0;

    if (!ctx) {
        GOSTerr(GOST_F_FILL_GOST2001_PARAMS, ERR_R_MALLOC_FAILURE);
        goto err;
    }

    BN_CTX_start(ctx);
    p = BN_CTX_get(ctx);
    a = BN_CTX_get(ctx);
    b = BN_CTX_get(ctx);
    x = BN_CTX_get(ctx);
    y = BN_CTX_get(ctx);
    q = BN_CTX_get(ctx);
    if (!p || !a || !b || !x || !y || !q) {
        GOSTerr(GOST_F_FILL_GOST2001_PARAMS, ERR_R_MALLOC_FAILURE);
        goto err;
    }
    while (params->nid != NID_undef && params->nid != nid)
        params++;
    if (params->nid == NID_undef) {
        GOSTerr(GOST_F_FILL_GOST2001_PARAMS,
                GOST_R_UNSUPPORTED_PARAMETER_SET);
        goto err;
    }
    if (!BN_hex2bn(&p, params->p)
        || !BN_hex2bn(&a, params->a)
        || !BN_hex2bn(&b, params->b)) {
        GOSTerr(GOST_F_FILL_GOST2001_PARAMS,
                ERR_R_INTERNAL_ERROR);
        goto err;
    }

    grp = EC_GROUP_new_curve_GFp(p, a, b, ctx);
    if (!grp)  {
        GOSTerr(GOST_F_FILL_GOST2001_PARAMS, ERR_R_MALLOC_FAILURE);
        goto err;
    }

    P = EC_POINT_new(grp);
    if (!P)  {
        GOSTerr(GOST_F_FILL_GOST2001_PARAMS, ERR_R_MALLOC_FAILURE);
        goto err;
    }

    if (!BN_hex2bn(&x, params->x)
        || !BN_hex2bn(&y, params->y)
        || !EC_POINT_set_affine_coordinates_GFp(grp, P, x, y, ctx)
        || !BN_hex2bn(&q, params->q))  {
        GOSTerr(GOST_F_FILL_GOST2001_PARAMS, ERR_R_INTERNAL_ERROR);
        goto err;
    }
#ifdef DEBUG_KEYS
    fprintf(stderr, "Set params index %d oid %s\nq=",
            (params - R3410_2001_paramset), OBJ_nid2sn(params->nid));
    BN_print_fp(stderr, q);
    fprintf(stderr, "\n");
#endif

    if (!EC_GROUP_set_generator(grp, P, q, NULL)) {
        GOSTerr(GOST_F_FILL_GOST2001_PARAMS, ERR_R_INTERNAL_ERROR);
        goto err;
    }
    EC_GROUP_set_curve_name(grp, params->nid);
    if (!EC_KEY_set_group(eckey, grp)) {
        GOSTerr(GOST_F_FILL_GOST2001_PARAMS, ERR_R_INTERNAL_ERROR);
        goto err;
    }
    ok = 1;
 err:
    EC_POINT_free(P);
    EC_GROUP_free(grp);
    if (ctx)
        BN_CTX_end(ctx);
    BN_CTX_free(ctx);
    return ok;
}
/***************************************************************************//**
 * Initialise the Mikey Sakke Parameter set storage. Presently there is only
 * one set (1), defined in RFC 6509, Appendix A.
 *
 * @return A boolean indicating success or failure.
 ******************************************************************************/
short ms_initParameterSets() {
    short   ret_val = 1;
    uint8_t c       = 0;
    BIGNUM *a       = NULL;
    BIGNUM *b       = NULL;
    BN_CTX *bn_ctx  = NULL;

    if (!ms_parameter_sets_initialised) {
        /* Clear out the storage structure */
        memset(ms_parameter_sets, 0, sizeof(ms_parameter_sets));

        /**********************************************************************/
        /* Add Parameter Set 1 (the default)                                  */
        /*   - these values are immutable and defined in RFC 6509, Appendix A.*/
        /**********************************************************************/
        ms_parameter_sets[c].iana_sakke_params = 1;

        ms_parameter_sets[c].n                 = 128;

        ms_parameter_sets[c].p = BN_new();
        BN_hex2bn(&ms_parameter_sets[c].p, MIKEY_SAKKE_p);

        ms_parameter_sets[c].q = BN_new();
        BN_hex2bn(&ms_parameter_sets[c].q, MIKEY_SAKKE_q);

        ms_parameter_sets[c].Px = BN_new();
        BN_hex2bn(&ms_parameter_sets[c].Px, MIKEY_SAKKE_Px);

        ms_parameter_sets[c].Py = BN_new();
        BN_hex2bn(&ms_parameter_sets[c].Py, MIKEY_SAKKE_Py);

        ms_parameter_sets[c].g = BN_new();
        BN_hex2bn(&ms_parameter_sets[c].g, MIKEY_SAKKE_g);

        ms_parameter_sets[c].data_set = ES_TRUE;

        if ((NULL != ms_parameter_sets[c].Px) &&
            (NULL != ms_parameter_sets[c].Py) &&
            (NULL != ms_parameter_sets[c].p)) {
            bn_ctx = BN_CTX_new();
            a      = BN_new();
            b      = BN_new();

            /* Create a curve E */
            BN_dec2bn(&a, "-3l"); /* Coefficient of 'x', see RFC 6508 Section 
                                   * 2.1 description of 'E'. 
                                   */
            BN_dec2bn(&b, "0");
            ms_parameter_sets[c].E =
                EC_GROUP_new_curve_GFp(ms_parameter_sets[c].p, a, b, bn_ctx);
            if (NULL != ms_parameter_sets[c].E) {

                ms_parameter_sets[c].P = EC_POINT_new(ms_parameter_sets[c].E);
                if (EC_POINT_set_affine_coordinates_GFp(
                    ms_parameter_sets[c].E,
                    ms_parameter_sets[c].P,
                    ms_parameter_sets[c].Px,
                    ms_parameter_sets[c].Py, bn_ctx)) {
         
                    /* Indicate the MS parameter set(s) storage is initialised. */
                    ret_val = 0;
                    ms_parameter_sets_initialised = ES_TRUE;
                    ret_val = 0;
                }
                else {
                    ES_ERROR("%s:%s:%d - MS parameter initialisation, unable to create Point 'P'!",
                        __FILE__, __FUNCTION__, __LINE__);
                }
            }
            else { 
                ES_ERROR("%s:%s:%d - MS parameter initialisation, unable to create curve 'E'!",
                    __FILE__, __FUNCTION__, __LINE__);
            }
            BN_CTX_free(bn_ctx);
            BN_clear_free(a);
            BN_clear_free(b);
            bn_ctx = NULL;
            a      = NULL;
            b      = NULL;
        }
        /* Else just fall through and fail. */

        /**********************************************************************/
        /* !!!!!        Add new Mikey Sakke parameter sets here.        !!!!! */
        /**********************************************************************/
        /* increment c to add new set. */

    }
    else {
        ES_ERROR("%s:%s:%d - MS parameter set already initialiased. Delete and reinitialise.",
            __FILE__, __FUNCTION__, __LINE__);

        /* Already initialised so return success. */
        ret_val = 0;
    }
    return ret_val;

} /* ms_initParameterSets */
Beispiel #18
0
int main()
{
    BIGNUM   *x, *y, *exp, *m, *order, *cof;
    BIGNUM   t, store[30];
    COMPLEX  *a, *b, *r;
    EC_POINT *point, *Q;
    int      i;

    x = BN_new();
    y = BN_new();
    order = BN_new();
    exp = BN_new();
    m = BN_new();

    a = COMP_new();
    b = COMP_new();
    r = COMP_new();
    for( i = 0; i < 30; i++ )
    	BN_init( &(store[i]) );

    if ( Context == NULL )
    	Context = BN_CTX_new();

    bi_init( &malloc );

    group = EC_GROUP_new( EC_GFp_simple_method() );
    if ( group == NULL )
    	goto err;

    if(!BN_set_word(m, 43l))
    	goto err;
    BN_set_word(x, 1l);
    BN_set_word(y, 0l);

    if ( !EC_GROUP_set_curve_GFp( group, m, x, y, Context) )
    	goto err;

    BN_set_word(x, 23l);
    BN_set_word(y, 8l);
    BN_set_word(order, 11l);

    point = EC_POINT_new( group );
    EC_POINT_set_affine_coordinates_GFp( group, point, x, y, Context );

    cof = BN_new();
    BN_set_word( cof, 4 );
    EC_GROUP_set_generator( group, point, order, cof );

    if ( EC_GROUP_check( group, Context ) )
    	printf(" group set is ok \n");

    TSS_DAA_ISSUER_KEY   issuer_key;
    TSS_DAA_ISSUER_PROOF issuer_proof;
    TSS_DAA_JOIN_issuer_setup(&issuer_key, &issuer_proof);


//    printf("\n");
//    BN_set_word(x, 41l);
//    BN_mod_inverse(x, x, m, Context);
//    BN_print_fp(stdout, x);
//
//    printf("\n");
//    BN_set_word(x, 11l);
//    BN_mod_inverse(x, x, m, Context);
//    BN_print_fp(stdout, x);

    char *str = "abcdefghijklmnop";
    Q = map_to_point( str );

    BN_set_word(x, 23l);
    BN_set_word(y, 8l);
    BN_set_word(order, 11l);

    Q = EC_POINT_new( group );
    EC_POINT_set_affine_coordinates_GFp( group, Q, x, y, Context );

    Tate( point, Q, order, 0,  store, a );
    printf("tate pair  t(p, Q) =:\n a.x: ");
    BN_print_fp(stdout, &a->x);
    printf("\na.y: ");
    BN_print_fp(stdout, &a->y);

    EC_POINT_dbl( group, point, point, Context);
    EC_POINT_get_affine_coordinates_GFp( group, point, x, y, Context);
    printf("2A.x =:\n");
    BN_print_fp(stdout, x);
    printf("2P.y= :\n");
    BN_print_fp(stdout, y);

    Tate( point, Q, order, 0,  store, a );
    printf("tate pair  t(2p, Q) =:\n a.x: ");
    BN_print_fp(stdout, &a->x);
    printf("\na.y: ");
    BN_print_fp(stdout, &a->y);

    BN_free( x );
    BN_free( y );
    BN_free( exp );
    BN_free( m );
    BN_free( order );
    BN_free( cof );

    COMP_free( a );
    COMP_free( b );
    COMP_free( r );

	return 0;
err:
	BN_free( &t );
	BN_free( x );
	BN_free( y );
	BN_free( exp );
	BN_free( m );
    BN_free( order );
    BN_free( cof );

	COMP_free( a );
	COMP_free( b );
	COMP_free( r );

	return 0;
}
Beispiel #19
0
void  SM2PKE_test3()
{
	/* test3 params */
	const char *p = "8542D69E4C044F18E8B92435BF6FF7DE457283915C45517D722EDB8B08F1DFC3";
	const char *a = "787968B4FA32C3FD2417842E73BBFEFF2F3C848B6831D7E0EC65228B3937E498";
	const char *b = "63E4C6D3B23B0C849CF84241484BFE48F61D59A5B16BA06E6E12D1DA27C5249A";
	const char *xG = "421DEBD61B62EAB6746434EBC3CC315E32220B3BADD50BDC4C4E6C147FEDD43D";
	const char *yG = "0680512BCBB42C07D47349D2153B70C4E5D7FDFCBFA36EA1A85841B9E46E09A2";
	const char *n = "8542D69E4C044F18E8B92435BF6FF7DD297720630485628D5AE74EE7C32E79B7";
	const char *dB = "1649AB77A00637BD5E2EFE283FBF353534AA7F7CB89463F208DDBC2920BB0DA0";
	const char *xB = "435B39CCA8F3B508C1488AFC67BE491A0F7BA07E581A0E4849A5CF70628A7E0A";
	const char *yB = "75DDBA78F15FEECB4C7895E2C1CDF5FE01DEBB2CDBADF45399CCF77BBA076A42";
	
	BIGNUM *bn_p = BN_new();
	BN_hex2bn(&bn_p, p);
	BIGNUM *bn_a = BN_new();
	BN_hex2bn(&bn_a, a);
	BIGNUM *bn_b = BN_new();
	BN_hex2bn(&bn_b, b);
	BIGNUM *bn_xG = BN_new();
	BN_hex2bn(&bn_xG, xG);
	BIGNUM *bn_yG = BN_new();
	BN_hex2bn(&bn_yG, yG);
	BIGNUM *bn_n = BN_new();
	BN_hex2bn(&bn_n, n);
	BIGNUM *bn_dB = BN_new();
	BN_hex2bn(&bn_dB, dB);
	BIGNUM *bn_xB = BN_new();
	BN_hex2bn(&bn_xB, xB);
	BIGNUM *bn_yB = BN_new();
	BN_hex2bn(&bn_yB, yB);
	
	BN_CTX *bn_ctx = BN_CTX_new();
	EC_GROUP *ec_group = EC_GROUP_new(EC_GFp_mont_method());
	EC_GROUP_set_curve_GFp(ec_group, bn_p, bn_a, bn_b, bn_ctx);

	EC_POINT *G = EC_POINT_new(ec_group);
	EC_POINT_set_affine_coordinates_GFp(ec_group, G, bn_xG, bn_yG, bn_ctx);
	BIGNUM *bn_h = BN_new();	/* cofactor h = #E(Fp) / n */
	BN_div(bn_h, NULL, bn_p, bn_n, bn_ctx);
	EC_GROUP_set_generator(ec_group, G, bn_n, bn_h);
	
	EC_POINT *PB = EC_POINT_new(ec_group);
	EC_POINT_set_affine_coordinates_GFp(ec_group, PB, bn_xB, bn_yB, bn_ctx);
	EC_KEY *ec_key_B = EC_KEY_new();
	EC_KEY_set_group(ec_key_B, ec_group);
	EC_KEY_set_private_key(ec_key_B, bn_dB);
	EC_KEY_set_public_key(ec_key_B, PB);
	
	BN_free(bn_p);
	BN_free(bn_a);
	BN_free(bn_b);
	BN_free(bn_n);
	BN_free(bn_xG);
	BN_free(bn_yG);
	BN_free(bn_dB);
	BN_free(bn_xB);
	BN_free(bn_yB);
	BN_free(bn_h);
	BN_CTX_free(bn_ctx);
	EC_POINT_free(G);
	EC_POINT_free(PB);
	EC_GROUP_free(ec_group);

	char *M = "encryption standard";
	char *ctest = "04245C26FB68B1DDDDB12C4B6BF9F2B6D5FE60A383B0D18D1C4144ABF17F6252"
	"E776CB9264C2A7E88E52B19903FDC47378F605E36811F5C07423A24B84400F01"
	"B8650053A89B41C418B0C3AAD00D886C002864679C3D7360C30156FAB7C80A02"
	"76712DA9D8094A634B766D3A285E07480653426D";
	BIGNUM *ct = BN_new();
	BN_hex2bn(&ct, ctest);
	unsigned char ct2bin[116];
	BN_bn2bin(ct, ct2bin);
	BN_free(ct);

	int mlen = strlen(M);
	int c1len = PRIME_SIZE / 8 * 2 + 1;
	int clen = c1len + mlen + HASH_V / 8;
	
	unsigned char *C = malloc(sizeof(unsigned char) * clen);
	sm2_pke_encrypt(C, M, mlen, ec_key_B);	
	if (memcmp(C, ct2bin, clen) == 0)
		printf("sm2_pke_encrypt passed.\n");
	else 
		printf("sm2_pke_encrypt failed.\n");
	free(C);
	
	int m1len = clen - c1len - HASH_V / 8;
	unsigned char *M1bin = malloc(sizeof(unsigned char) * m1len);
	sm2_pke_decrypt((char *)ct2bin, M1bin, m1len, ec_key_B);	
	if (memcmp(M1bin, M, m1len) == 0)
		printf("sm2_pke_decrypt passed.\n");
	else 
		printf("sm2_pke_decrypt failed.\n");
	free(M1bin);

	EC_KEY_free(ec_key_B);
}
Beispiel #20
0
static void
eap_pwd_process_commit_resp(struct eap_sm *sm, struct eap_pwd_data *data,
			    const u8 *payload, size_t payload_len)
{
	u8 *ptr;
	BIGNUM *x = NULL, *y = NULL, *cofactor = NULL;
	EC_POINT *K = NULL, *point = NULL;
	int res = 0;

	wpa_printf(MSG_DEBUG, "EAP-pwd: Received commit response");

	if (((data->peer_scalar = BN_new()) == NULL) ||
	    ((data->k = BN_new()) == NULL) ||
	    ((cofactor = BN_new()) == NULL) ||
	    ((x = BN_new()) == NULL) ||
	    ((y = BN_new()) == NULL) ||
	    ((point = EC_POINT_new(data->grp->group)) == NULL) ||
	    ((K = EC_POINT_new(data->grp->group)) == NULL) ||
	    ((data->peer_element = EC_POINT_new(data->grp->group)) == NULL)) {
		wpa_printf(MSG_INFO, "EAP-PWD (server): peer data allocation "
			   "fail");
		goto fin;
	}

	if (!EC_GROUP_get_cofactor(data->grp->group, cofactor, NULL)) {
		wpa_printf(MSG_INFO, "EAP-PWD (server): unable to get "
			   "cofactor for curve");
		goto fin;
	}

	/* element, x then y, followed by scalar */
	ptr = (u8 *) payload;
	BN_bin2bn(ptr, BN_num_bytes(data->grp->prime), x);
	ptr += BN_num_bytes(data->grp->prime);
	BN_bin2bn(ptr, BN_num_bytes(data->grp->prime), y);
	ptr += BN_num_bytes(data->grp->prime);
	BN_bin2bn(ptr, BN_num_bytes(data->grp->order), data->peer_scalar);
	if (!EC_POINT_set_affine_coordinates_GFp(data->grp->group,
						 data->peer_element, x, y,
						 data->bnctx)) {
		wpa_printf(MSG_INFO, "EAP-PWD (server): setting peer element "
			   "fail");
		goto fin;
	}

	/* check to ensure peer's element is not in a small sub-group */
	if (BN_cmp(cofactor, BN_value_one())) {
		if (!EC_POINT_mul(data->grp->group, point, NULL,
				  data->peer_element, cofactor, NULL)) {
			wpa_printf(MSG_INFO, "EAP-PWD (server): cannot "
				   "multiply peer element by order");
			goto fin;
		}
		if (EC_POINT_is_at_infinity(data->grp->group, point)) {
			wpa_printf(MSG_INFO, "EAP-PWD (server): peer element "
				   "is at infinity!\n");
			goto fin;
		}
	}

	/* compute the shared key, k */
	if ((!EC_POINT_mul(data->grp->group, K, NULL, data->grp->pwe,
			   data->peer_scalar, data->bnctx)) ||
	    (!EC_POINT_add(data->grp->group, K, K, data->peer_element,
			   data->bnctx)) ||
	    (!EC_POINT_mul(data->grp->group, K, NULL, K, data->private_value,
			   data->bnctx))) {
		wpa_printf(MSG_INFO, "EAP-PWD (server): computing shared key "
			   "fail");
		goto fin;
	}

	/* ensure that the shared key isn't in a small sub-group */
	if (BN_cmp(cofactor, BN_value_one())) {
		if (!EC_POINT_mul(data->grp->group, K, NULL, K, cofactor,
				  NULL)) {
			wpa_printf(MSG_INFO, "EAP-PWD (server): cannot "
				   "multiply shared key point by order!\n");
			goto fin;
		}
	}

	/*
	 * This check is strictly speaking just for the case above where
	 * co-factor > 1 but it was suggested that even though this is probably
	 * never going to happen it is a simple and safe check "just to be
	 * sure" so let's be safe.
	 */
	if (EC_POINT_is_at_infinity(data->grp->group, K)) {
		wpa_printf(MSG_INFO, "EAP-PWD (server): shared key point is "
			   "at infinity");
		goto fin;
	}
	if (!EC_POINT_get_affine_coordinates_GFp(data->grp->group, K, data->k,
						 NULL, data->bnctx)) {
		wpa_printf(MSG_INFO, "EAP-PWD (server): unable to extract "
			   "shared secret from secret point");
		goto fin;
	}
	res = 1;

fin:
	EC_POINT_free(K);
	EC_POINT_free(point);
	BN_free(cofactor);
	BN_free(x);
	BN_free(y);

	if (res)
		eap_pwd_state(data, PWD_Confirm_Req);
	else
		eap_pwd_state(data, FAILURE);
}
Beispiel #21
0
static EC_GROUP *ec_group_new_from_data(const struct built_in_curve *curve) {
  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;
  unsigned param_len;
  const EC_METHOD *meth;
  const struct curve_data *data;
  const uint8_t *params;

  if ((ctx = BN_CTX_new()) == NULL) {
    OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
    goto err;
  }

  data = curve->data;
  param_len = data->param_len;
  params = data->data;

  if (!(p = BN_bin2bn(params + 0 * param_len, param_len, NULL)) ||
      !(a = BN_bin2bn(params + 1 * param_len, param_len, NULL)) ||
      !(b = BN_bin2bn(params + 2 * param_len, param_len, NULL))) {
    OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
    goto err;
  }

  if (curve->method != 0) {
    meth = curve->method();
    if (((group = ec_group_new(meth)) == NULL) ||
        (!(group->meth->group_set_curve(group, p, a, b, ctx)))) {
      OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
      goto err;
    }
  } else {
    if ((group = EC_GROUP_new_curve_GFp(p, a, b, ctx)) == NULL) {
      OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
      goto err;
    }
  }

  if ((P = EC_POINT_new(group)) == NULL) {
    OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
    goto err;
  }

  if (!(x = BN_bin2bn(params + 3 * param_len, param_len, NULL)) ||
      !(y = BN_bin2bn(params + 4 * param_len, param_len, NULL))) {
    OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
    goto err;
  }

  if (!EC_POINT_set_affine_coordinates_GFp(group, P, x, y, ctx)) {
    OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
    goto err;
  }
  if (!(order = BN_bin2bn(params + 5 * param_len, param_len, NULL)) ||
      !BN_set_word(x, (BN_ULONG)data->cofactor)) {
    OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
    goto err;
  }

  group->generator = P;
  P = NULL;
  if (!BN_copy(&group->order, order) ||
      !BN_set_word(&group->cofactor, (BN_ULONG)data->cofactor)) {
    OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
    goto err;
  }

  ok = 1;

err:
  if (!ok) {
    EC_GROUP_free(group);
    group = NULL;
  }
  EC_POINT_free(P);
  BN_CTX_free(ctx);
  BN_free(p);
  BN_free(a);
  BN_free(b);
  BN_free(order);
  BN_free(x);
  BN_free(y);
  return group;
}
Beispiel #22
0
static int ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
                                   const uint8_t *buf, size_t len,
                                   BN_CTX *ctx) {
  point_conversion_form_t form;
  int y_bit;
  BN_CTX *new_ctx = NULL;
  BIGNUM *x, *y;
  size_t field_len, enc_len;
  int ret = 0;

  if (len == 0) {
    OPENSSL_PUT_ERROR(EC, EC_R_BUFFER_TOO_SMALL);
    return 0;
  }
  form = buf[0];
  y_bit = form & 1;
  form = form & ~1U;
  if ((form != POINT_CONVERSION_COMPRESSED &&
       form != POINT_CONVERSION_UNCOMPRESSED) ||
      (form == POINT_CONVERSION_UNCOMPRESSED && y_bit)) {
    OPENSSL_PUT_ERROR(EC, EC_R_INVALID_ENCODING);
    return 0;
  }

  field_len = BN_num_bytes(&group->field);
  enc_len =
      (form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2 * field_len;

  if (len != enc_len) {
    OPENSSL_PUT_ERROR(EC, EC_R_INVALID_ENCODING);
    return 0;
  }

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

  BN_CTX_start(ctx);
  x = BN_CTX_get(ctx);
  y = BN_CTX_get(ctx);
  if (x == NULL || y == NULL) {
    goto err;
  }

  if (!BN_bin2bn(buf + 1, field_len, x)) {
    goto err;
  }
  if (BN_ucmp(x, &group->field) >= 0) {
    OPENSSL_PUT_ERROR(EC, EC_R_INVALID_ENCODING);
    goto err;
  }

  if (form == POINT_CONVERSION_COMPRESSED) {
    if (!EC_POINT_set_compressed_coordinates_GFp(group, point, x, y_bit, ctx)) {
      goto err;
    }
  } else {
    if (!BN_bin2bn(buf + 1 + field_len, field_len, y)) {
      goto err;
    }
    if (BN_ucmp(y, &group->field) >= 0) {
      OPENSSL_PUT_ERROR(EC, EC_R_INVALID_ENCODING);
      goto err;
    }

    if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx)) {
      goto err;
    }
  }

  ret = 1;

err:
  BN_CTX_end(ctx);
  BN_CTX_free(new_ctx);
  return ret;
}
Beispiel #23
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;

}
void
sshbuf_getput_crypto_tests(void)
{
	struct sshbuf *p1;
	const u_char *d;
	size_t s;
	BIGNUM *bn, *bn2, *bn_x, *bn_y;
	/* This one has num_bits != num_bytes * 8 to test bignum1 encoding */
	const char *hexbn1 = "0102030405060708090a0b0c0d0e0f10";
	/* This one has MSB set to test bignum2 encoding negative-avoidance */
	const char *hexbn2 = "f0e0d0c0b0a0908070605040302010007fff11";
	u_char expbn1[] = {
		0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
		0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
	};
	u_char expbn2[] = {
		0xf0, 0xe0, 0xd0, 0xc0, 0xb0, 0xa0, 0x90, 0x80,
		0x70, 0x60, 0x50, 0x40, 0x30, 0x20, 0x10, 0x00,
		0x7f, 0xff, 0x11
	};
	int ec256_nid = NID_X9_62_prime256v1;
	char *ec256_x = "0C828004839D0106AA59575216191357"
		        "34B451459DADB586677EF9DF55784999";
	char *ec256_y = "4D196B50F0B4E94B3C73E3A9D4CD9DF2"
	                "C8F9A35E42BDD047550F69D80EC23CD4";
	u_char expec256[] = {
		0x04,
		0x0c, 0x82, 0x80, 0x04, 0x83, 0x9d, 0x01, 0x06,
		0xaa, 0x59, 0x57, 0x52, 0x16, 0x19, 0x13, 0x57,
		0x34, 0xb4, 0x51, 0x45, 0x9d, 0xad, 0xb5, 0x86,
		0x67, 0x7e, 0xf9, 0xdf, 0x55, 0x78, 0x49, 0x99,
		0x4d, 0x19, 0x6b, 0x50, 0xf0, 0xb4, 0xe9, 0x4b,
		0x3c, 0x73, 0xe3, 0xa9, 0xd4, 0xcd, 0x9d, 0xf2,
		0xc8, 0xf9, 0xa3, 0x5e, 0x42, 0xbd, 0xd0, 0x47,
		0x55, 0x0f, 0x69, 0xd8, 0x0e, 0xc2, 0x3c, 0xd4
	};
	EC_KEY *eck;
	EC_POINT *ecp;
	int r;

#define MKBN(b, bnn) \
	do { \
		bnn = NULL; \
		ASSERT_INT_GT(BN_hex2bn(&bnn, b), 0); \
	} while (0)

	TEST_START("sshbuf_put_bignum1");
	MKBN(hexbn1, bn);
	p1 = sshbuf_new();
	ASSERT_PTR_NE(p1, NULL);
	ASSERT_INT_EQ(sshbuf_put_bignum1(p1, bn), 0);
	ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(expbn1) + 2);
	ASSERT_U16_EQ(PEEK_U16(sshbuf_ptr(p1)), (u_int16_t)BN_num_bits(bn));
	ASSERT_MEM_EQ(sshbuf_ptr(p1) + 2, expbn1, sizeof(expbn1));
	BN_free(bn);
	sshbuf_free(p1);
	TEST_DONE();

	TEST_START("sshbuf_put_bignum1 limited");
	MKBN(hexbn1, bn);
	p1 = sshbuf_new();
	ASSERT_PTR_NE(p1, NULL);
	ASSERT_INT_EQ(sshbuf_set_max_size(p1, sizeof(expbn1) + 1), 0);
	r = sshbuf_put_bignum1(p1, bn);
	ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE);
	ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
	BN_free(bn);
	sshbuf_free(p1);
	TEST_DONE();

	TEST_START("sshbuf_put_bignum1 bn2");
	MKBN(hexbn2, bn);
	p1 = sshbuf_new();
	ASSERT_PTR_NE(p1, NULL);
	ASSERT_INT_EQ(sshbuf_put_bignum1(p1, bn), 0);
	ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(expbn2) + 2);
	ASSERT_U16_EQ(PEEK_U16(sshbuf_ptr(p1)), (u_int16_t)BN_num_bits(bn));
	ASSERT_MEM_EQ(sshbuf_ptr(p1) + 2, expbn2, sizeof(expbn2));
	BN_free(bn);
	sshbuf_free(p1);
	TEST_DONE();

	TEST_START("sshbuf_put_bignum1 bn2 limited");
	MKBN(hexbn2, bn);
	p1 = sshbuf_new();
	ASSERT_PTR_NE(p1, NULL);
	ASSERT_INT_EQ(sshbuf_set_max_size(p1, sizeof(expbn1) + 1), 0);
	r = sshbuf_put_bignum1(p1, bn);
	ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE);
	ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
	BN_free(bn);
	sshbuf_free(p1);
	TEST_DONE();

	TEST_START("sshbuf_put_bignum2");
	MKBN(hexbn1, bn);
	p1 = sshbuf_new();
	ASSERT_PTR_NE(p1, NULL);
	ASSERT_INT_EQ(sshbuf_put_bignum2(p1, bn), 0);
	ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(expbn1) + 4);
	ASSERT_U32_EQ(PEEK_U32(sshbuf_ptr(p1)), (u_int32_t)BN_num_bytes(bn));
	ASSERT_MEM_EQ(sshbuf_ptr(p1) + 4, expbn1, sizeof(expbn1));
	BN_free(bn);
	sshbuf_free(p1);
	TEST_DONE();

	TEST_START("sshbuf_put_bignum2 limited");
	MKBN(hexbn1, bn);
	p1 = sshbuf_new();
	ASSERT_PTR_NE(p1, NULL);
	ASSERT_INT_EQ(sshbuf_set_max_size(p1, sizeof(expbn1) + 3), 0);
	r = sshbuf_put_bignum2(p1, bn);
	ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE);
	ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
	BN_free(bn);
	sshbuf_free(p1);
	TEST_DONE();

	TEST_START("sshbuf_put_bignum2 bn2");
	MKBN(hexbn2, bn);
	p1 = sshbuf_new();
	ASSERT_PTR_NE(p1, NULL);
	ASSERT_INT_EQ(sshbuf_put_bignum2(p1, bn), 0);
	ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(expbn2) + 4 + 1); /* MSB */
	ASSERT_U32_EQ(PEEK_U32(sshbuf_ptr(p1)), (u_int32_t)BN_num_bytes(bn) + 1);
	ASSERT_U8_EQ(*(sshbuf_ptr(p1) + 4), 0x00);
	ASSERT_MEM_EQ(sshbuf_ptr(p1) + 5, expbn2, sizeof(expbn2));
	BN_free(bn);
	sshbuf_free(p1);
	TEST_DONE();

	TEST_START("sshbuf_put_bignum2 bn2 limited");
	MKBN(hexbn2, bn);
	p1 = sshbuf_new();
	ASSERT_PTR_NE(p1, NULL);
	ASSERT_INT_EQ(sshbuf_set_max_size(p1, sizeof(expbn2) + 3), 0);
	r = sshbuf_put_bignum2(p1, bn);
	ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE);
	ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
	BN_free(bn);
	sshbuf_free(p1);
	TEST_DONE();

	TEST_START("sshbuf_get_bignum1");
	MKBN(hexbn1, bn);
	p1 = sshbuf_new();
	ASSERT_PTR_NE(p1, NULL);
	ASSERT_INT_EQ(sshbuf_put_u16(p1, BN_num_bits(bn)), 0);
	ASSERT_INT_EQ(sshbuf_put(p1, expbn1, sizeof(expbn1)), 0);
	ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2 + sizeof(expbn1));
	ASSERT_INT_EQ(sshbuf_put_u16(p1, 0xd00f), 0);
	bn2 = BN_new();
	ASSERT_INT_EQ(sshbuf_get_bignum1(p1, bn2), 0);
	ASSERT_BIGNUM_EQ(bn, bn2);
	ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2);
	BN_free(bn);
	BN_free(bn2);
	sshbuf_free(p1);
	TEST_DONE();

	TEST_START("sshbuf_get_bignum1 truncated");
	MKBN(hexbn1, bn);
	p1 = sshbuf_new();
	ASSERT_PTR_NE(p1, NULL);
	ASSERT_INT_EQ(sshbuf_put_u16(p1, BN_num_bits(bn)), 0);
	ASSERT_INT_EQ(sshbuf_put(p1, expbn1, sizeof(expbn1) - 1), 0);
	ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2 + sizeof(expbn1) - 1);
	bn2 = BN_new();
	r = sshbuf_get_bignum1(p1, bn2);
	ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
	ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2 + sizeof(expbn1) - 1);
	BN_free(bn);
	BN_free(bn2);
	sshbuf_free(p1);
	TEST_DONE();

	TEST_START("sshbuf_get_bignum1 giant");
	MKBN(hexbn1, bn);
	p1 = sshbuf_new();
	ASSERT_PTR_NE(p1, NULL);
	ASSERT_INT_EQ(sshbuf_put_u16(p1, 0xffff), 0);
	ASSERT_INT_EQ(sshbuf_reserve(p1, (0xffff + 7) / 8, NULL), 0);
	ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2 + ((0xffff + 7) / 8));
	bn2 = BN_new();
	r = sshbuf_get_bignum1(p1, bn2);
	ASSERT_INT_EQ(r, SSH_ERR_BIGNUM_TOO_LARGE);
	ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2 + ((0xffff + 7) / 8));
	BN_free(bn);
	BN_free(bn2);
	sshbuf_free(p1);
	TEST_DONE();

	TEST_START("sshbuf_get_bignum1 bn2");
	MKBN(hexbn2, bn);
	p1 = sshbuf_new();
	ASSERT_PTR_NE(p1, NULL);
	ASSERT_INT_EQ(sshbuf_put_u16(p1, BN_num_bits(bn)), 0);
	ASSERT_INT_EQ(sshbuf_put(p1, expbn2, sizeof(expbn2)), 0);
	ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2 + sizeof(expbn2));
	ASSERT_INT_EQ(sshbuf_put_u16(p1, 0xd00f), 0);
	bn2 = BN_new();
	ASSERT_INT_EQ(sshbuf_get_bignum1(p1, bn2), 0);
	ASSERT_BIGNUM_EQ(bn, bn2);
	ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2);
	BN_free(bn);
	BN_free(bn2);
	sshbuf_free(p1);
	TEST_DONE();

	TEST_START("sshbuf_get_bignum1 bn2 truncated");
	MKBN(hexbn2, bn);
	p1 = sshbuf_new();
	ASSERT_PTR_NE(p1, NULL);
	ASSERT_INT_EQ(sshbuf_put_u16(p1, BN_num_bits(bn)), 0);
	ASSERT_INT_EQ(sshbuf_put(p1, expbn2, sizeof(expbn2) - 1), 0);
	ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2 + sizeof(expbn2) - 1);
	bn2 = BN_new();
	r = sshbuf_get_bignum1(p1, bn2);
	ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
	ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2 + sizeof(expbn2) - 1);
	BN_free(bn);
	BN_free(bn2);
	sshbuf_free(p1);
	TEST_DONE();

	TEST_START("sshbuf_get_bignum2");
	MKBN(hexbn1, bn);
	p1 = sshbuf_new();
	ASSERT_PTR_NE(p1, NULL);
	ASSERT_INT_EQ(sshbuf_put_u32(p1, BN_num_bytes(bn)), 0);
	ASSERT_INT_EQ(sshbuf_put(p1, expbn1, sizeof(expbn1)), 0);
	ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4 + sizeof(expbn1));
	ASSERT_INT_EQ(sshbuf_put_u16(p1, 0xd00f), 0);
	bn2 = BN_new();
	ASSERT_INT_EQ(sshbuf_get_bignum2(p1, bn2), 0);
	ASSERT_BIGNUM_EQ(bn, bn2);
	ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2);
	BN_free(bn);
	BN_free(bn2);
	sshbuf_free(p1);
	TEST_DONE();

	TEST_START("sshbuf_get_bignum2 truncated");
	MKBN(hexbn1, bn);
	p1 = sshbuf_new();
	ASSERT_PTR_NE(p1, NULL);
	ASSERT_INT_EQ(sshbuf_put_u32(p1, BN_num_bytes(bn)), 0);
	ASSERT_INT_EQ(sshbuf_put(p1, expbn1, sizeof(expbn1) - 1), 0);
	bn2 = BN_new();
	r = sshbuf_get_bignum2(p1, bn2);
	ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
	ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(expbn1) + 3);
	BN_free(bn);
	BN_free(bn2);
	sshbuf_free(p1);
	TEST_DONE();

	TEST_START("sshbuf_get_bignum2 giant");
	MKBN(hexbn1, bn);
	p1 = sshbuf_new();
	ASSERT_PTR_NE(p1, NULL);
	ASSERT_INT_EQ(sshbuf_put_u32(p1, 65536), 0);
	ASSERT_INT_EQ(sshbuf_reserve(p1, 65536, NULL), 0);
	bn2 = BN_new();
	r = sshbuf_get_bignum2(p1, bn2);
	ASSERT_INT_EQ(r, SSH_ERR_BIGNUM_TOO_LARGE);
	ASSERT_SIZE_T_EQ(sshbuf_len(p1), 65536 + 4);
	BN_free(bn);
	BN_free(bn2);
	sshbuf_free(p1);
	TEST_DONE();

	TEST_START("sshbuf_get_bignum2 bn2");
	MKBN(hexbn2, bn);
	p1 = sshbuf_new();
	ASSERT_PTR_NE(p1, NULL);
	ASSERT_INT_EQ(sshbuf_put_u32(p1, BN_num_bytes(bn) + 1), 0); /* MSB */
	ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x00), 0);
	ASSERT_INT_EQ(sshbuf_put(p1, expbn2, sizeof(expbn2)), 0);
	ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4 + 1 + sizeof(expbn2));
	ASSERT_INT_EQ(sshbuf_put_u16(p1, 0xd00f), 0);
	bn2 = BN_new();
	ASSERT_INT_EQ(sshbuf_get_bignum2(p1, bn2), 0);
	ASSERT_BIGNUM_EQ(bn, bn2);
	ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2);
	BN_free(bn);
	BN_free(bn2);
	sshbuf_free(p1);
	TEST_DONE();

	TEST_START("sshbuf_get_bignum2 bn2 truncated");
	MKBN(hexbn2, bn);
	p1 = sshbuf_new();
	ASSERT_PTR_NE(p1, NULL);
	ASSERT_INT_EQ(sshbuf_put_u32(p1, BN_num_bytes(bn) + 1), 0);
	ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x00), 0);
	ASSERT_INT_EQ(sshbuf_put(p1, expbn2, sizeof(expbn2) - 1), 0);
	bn2 = BN_new();
	r = sshbuf_get_bignum2(p1, bn2);
	ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
	ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(expbn2) + 1 + 4 - 1);
	BN_free(bn);
	BN_free(bn2);
	sshbuf_free(p1);
	TEST_DONE();

	TEST_START("sshbuf_get_bignum2 bn2 negative");
	MKBN(hexbn2, bn);
	p1 = sshbuf_new();
	ASSERT_PTR_NE(p1, NULL);
	ASSERT_INT_EQ(sshbuf_put_u32(p1, BN_num_bytes(bn)), 0);
	ASSERT_INT_EQ(sshbuf_put(p1, expbn2, sizeof(expbn2)), 0);
	bn2 = BN_new();
	r = sshbuf_get_bignum2(p1, bn2);
	ASSERT_INT_EQ(r, SSH_ERR_BIGNUM_IS_NEGATIVE);
	ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(expbn2) + 4);
	BN_free(bn);
	BN_free(bn2);
	sshbuf_free(p1);
	TEST_DONE();

	TEST_START("sshbuf_put_ec");
	eck = EC_KEY_new_by_curve_name(ec256_nid);
	ASSERT_PTR_NE(eck, NULL);
	ecp = EC_POINT_new(EC_KEY_get0_group(eck));
	ASSERT_PTR_NE(ecp, NULL);
	MKBN(ec256_x, bn_x);
	MKBN(ec256_y, bn_y);
	ASSERT_INT_EQ(EC_POINT_set_affine_coordinates_GFp(
	    EC_KEY_get0_group(eck), ecp, bn_x, bn_y, NULL), 1);
	ASSERT_INT_EQ(EC_KEY_set_public_key(eck, ecp), 1);
	EC_POINT_free(ecp);
	p1 = sshbuf_new();
	ASSERT_PTR_NE(p1, NULL);
	ASSERT_INT_EQ(sshbuf_put_eckey(p1, eck), 0);
	ASSERT_INT_EQ(sshbuf_get_string_direct(p1, &d, &s), 0);
	ASSERT_SIZE_T_EQ(s, sizeof(expec256));
	ASSERT_MEM_EQ(d, expec256, sizeof(expec256));
	sshbuf_free(p1);
	EC_KEY_free(eck);
	TEST_DONE();

	TEST_START("sshbuf_get_ec");
	eck = EC_KEY_new_by_curve_name(ec256_nid);
	ASSERT_PTR_NE(eck, NULL);
	p1 = sshbuf_new();
	ASSERT_PTR_NE(p1, NULL);
	ASSERT_INT_EQ(sshbuf_put_string(p1, expec256, sizeof(expec256)), 0);
	ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(expec256) + 4);
	ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x00), 0);
	ASSERT_INT_EQ(sshbuf_get_eckey(p1, eck), 0);
	bn_x = BN_new();
	bn_y = BN_new();
	ASSERT_PTR_NE(bn_x, NULL);
	ASSERT_PTR_NE(bn_y, NULL);
	ASSERT_INT_EQ(EC_POINT_get_affine_coordinates_GFp(
	    EC_KEY_get0_group(eck), EC_KEY_get0_public_key(eck),
	    bn_x, bn_y, NULL), 1);
	MKBN(ec256_x, bn);
	MKBN(ec256_y, bn2);
	ASSERT_INT_EQ(BN_cmp(bn_x, bn), 0);
	ASSERT_INT_EQ(BN_cmp(bn_y, bn2), 0);
	ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1);
	sshbuf_free(p1);
	EC_KEY_free(eck);
	BN_free(bn_x);
	BN_free(bn_y);
	BN_free(bn);
	BN_free(bn2);
	TEST_DONE();
}
static void
eap_pwd_perform_commit_exchange(struct eap_sm *sm, struct eap_pwd_data *data,
				struct eap_method_ret *ret,
				const struct wpabuf *reqData,
				const u8 *payload, size_t payload_len)
{
	EC_POINT *K = NULL, *point = NULL;
	BIGNUM *mask = NULL, *x = NULL, *y = NULL, *cofactor = NULL;
	u16 offset;
	u8 *ptr, *scalar = NULL, *element = NULL;

	if (((data->private_value = BN_new()) == NULL) ||
	    ((data->my_element = EC_POINT_new(data->grp->group)) == NULL) ||
	    ((cofactor = BN_new()) == NULL) ||
	    ((data->my_scalar = BN_new()) == NULL) ||
	    ((mask = BN_new()) == NULL)) {
		wpa_printf(MSG_INFO, "EAP-PWD (peer): scalar allocation fail");
		goto fin;
	}

	if (!EC_GROUP_get_cofactor(data->grp->group, cofactor, NULL)) {
		wpa_printf(MSG_INFO, "EAP-pwd (peer): unable to get cofactor "
			   "for curve");
		goto fin;
	}

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

	if (!EC_POINT_mul(data->grp->group, data->my_element, NULL,
			  data->grp->pwe, mask, data->bnctx)) {
		wpa_printf(MSG_INFO, "EAP-PWD (peer): element allocation "
			   "fail");
		eap_pwd_state(data, FAILURE);
		goto fin;
	}

	if (!EC_POINT_invert(data->grp->group, data->my_element, data->bnctx))
	{
		wpa_printf(MSG_INFO, "EAP-PWD (peer): element inversion fail");
		goto fin;
	}
	BN_free(mask);

	if (((x = BN_new()) == NULL) ||
	    ((y = BN_new()) == NULL)) {
		wpa_printf(MSG_INFO, "EAP-PWD (peer): point allocation fail");
		goto fin;
	}

	/* process the request */
	if (((data->server_scalar = BN_new()) == NULL) ||
	    ((data->k = BN_new()) == NULL) ||
	    ((K = EC_POINT_new(data->grp->group)) == NULL) ||
	    ((point = EC_POINT_new(data->grp->group)) == NULL) ||
	    ((data->server_element = EC_POINT_new(data->grp->group)) == NULL))
	{
		wpa_printf(MSG_INFO, "EAP-PWD (peer): peer data allocation "
			   "fail");
		goto fin;
	}

	/* element, x then y, followed by scalar */
	ptr = (u8 *) payload;
	BN_bin2bn(ptr, BN_num_bytes(data->grp->prime), x);
	ptr += BN_num_bytes(data->grp->prime);
	BN_bin2bn(ptr, BN_num_bytes(data->grp->prime), y);
	ptr += BN_num_bytes(data->grp->prime);
	BN_bin2bn(ptr, BN_num_bytes(data->grp->order), data->server_scalar);
	if (!EC_POINT_set_affine_coordinates_GFp(data->grp->group,
						 data->server_element, x, y,
						 data->bnctx)) {
		wpa_printf(MSG_INFO, "EAP-PWD (peer): setting peer element "
			   "fail");
		goto fin;
	}

	/* check to ensure server's element is not in a small sub-group */
	if (BN_cmp(cofactor, BN_value_one())) {
		if (!EC_POINT_mul(data->grp->group, point, NULL,
				  data->server_element, cofactor, NULL)) {
			wpa_printf(MSG_INFO, "EAP-PWD (peer): cannot multiply "
				   "server element by order!\n");
			goto fin;
		}
		if (EC_POINT_is_at_infinity(data->grp->group, point)) {
			wpa_printf(MSG_INFO, "EAP-PWD (peer): server element "
				   "is at infinity!\n");
			goto fin;
		}
	}

	/* compute the shared key, k */
	if ((!EC_POINT_mul(data->grp->group, K, NULL, data->grp->pwe,
			   data->server_scalar, data->bnctx)) ||
	    (!EC_POINT_add(data->grp->group, K, K, data->server_element,
			   data->bnctx)) ||
	    (!EC_POINT_mul(data->grp->group, K, NULL, K, data->private_value,
			   data->bnctx))) {
		wpa_printf(MSG_INFO, "EAP-PWD (peer): computing shared key "
			   "fail");
		goto fin;
	}

	/* ensure that the shared key isn't in a small sub-group */
	if (BN_cmp(cofactor, BN_value_one())) {
		if (!EC_POINT_mul(data->grp->group, K, NULL, K, cofactor,
				  NULL)) {
			wpa_printf(MSG_INFO, "EAP-PWD (peer): cannot multiply "
				   "shared key point by order");
			goto fin;
		}
	}

	/*
	 * This check is strictly speaking just for the case above where
	 * co-factor > 1 but it was suggested that even though this is probably
	 * never going to happen it is a simple and safe check "just to be
	 * sure" so let's be safe.
	 */
	if (EC_POINT_is_at_infinity(data->grp->group, K)) {
		wpa_printf(MSG_INFO, "EAP-PWD (peer): shared key point is at "
			   "infinity!\n");
		goto fin;
	}

	if (!EC_POINT_get_affine_coordinates_GFp(data->grp->group, K, data->k,
						 NULL, data->bnctx)) {
		wpa_printf(MSG_INFO, "EAP-PWD (peer): unable to extract "
			   "shared secret from point");
		goto fin;
	}

	/* now do the response */
	if (!EC_POINT_get_affine_coordinates_GFp(data->grp->group,
						 data->my_element, x, y,
						 data->bnctx)) {
		wpa_printf(MSG_INFO, "EAP-PWD (peer): point assignment fail");
		goto fin;
	}

	if (((scalar = os_malloc(BN_num_bytes(data->grp->order))) == NULL) ||
	    ((element = os_malloc(BN_num_bytes(data->grp->prime) * 2)) ==
	     NULL)) {
		wpa_printf(MSG_INFO, "EAP-PWD (peer): data allocation fail");
		goto fin;
	}

	/*
	 * bignums occupy as little memory as possible so one that is
	 * sufficiently smaller than the prime or order might need pre-pending
	 * with zeros.
	 */
	os_memset(scalar, 0, BN_num_bytes(data->grp->order));
	os_memset(element, 0, BN_num_bytes(data->grp->prime) * 2);
	offset = BN_num_bytes(data->grp->order) -
		BN_num_bytes(data->my_scalar);
	BN_bn2bin(data->my_scalar, scalar + offset);

	offset = BN_num_bytes(data->grp->prime) - BN_num_bytes(x);
	BN_bn2bin(x, element + offset);
	offset = BN_num_bytes(data->grp->prime) - BN_num_bytes(y);
	BN_bn2bin(y, element + BN_num_bytes(data->grp->prime) + offset);

	data->outbuf = wpabuf_alloc(BN_num_bytes(data->grp->order) +
				    2 * BN_num_bytes(data->grp->prime));
	if (data->outbuf == NULL)
		goto fin;

	/* we send the element as (x,y) follwed by the scalar */
	wpabuf_put_data(data->outbuf, element,
			2 * BN_num_bytes(data->grp->prime));
	wpabuf_put_data(data->outbuf, scalar, BN_num_bytes(data->grp->order));

fin:
	os_free(scalar);
	os_free(element);
	BN_free(x);
	BN_free(y);
	BN_free(cofactor);
	EC_POINT_free(K);
	EC_POINT_free(point);
	if (data->outbuf == NULL)
		eap_pwd_state(data, FAILURE);
	else
		eap_pwd_state(data, PWD_Confirm_Req);
}
Beispiel #26
0
/*
 * Fills EC_KEY structure hidden in the app_data field of DSA structure
 * with parameter information, extracted from parameter array in
 * params.c file.
 *
 * Also fils DSA->q field with copy of EC_GROUP order field to make
 * DSA_size function work
 */
int fill_GOST_EC_params(EC_KEY *eckey, int nid)
{
    R3410_ec_params *params = gost_nid2params(nid);
    EC_GROUP *grp = NULL;
    EC_POINT *P = NULL;
    BIGNUM *p = NULL, *q = NULL, *a = NULL, *b = NULL, *x = NULL, *y = NULL;
    BN_CTX *ctx;
    int ok = 0;

    if (!eckey || !params) {
        GOSTerr(GOST_F_FILL_GOST_EC_PARAMS, GOST_R_UNSUPPORTED_PARAMETER_SET);
        return 0;
    }

    if (!(ctx = BN_CTX_new())) {
        GOSTerr(GOST_F_FILL_GOST_EC_PARAMS, ERR_R_MALLOC_FAILURE);
        return 0;
    }

    BN_CTX_start(ctx);
    p = BN_CTX_get(ctx);
    a = BN_CTX_get(ctx);
    b = BN_CTX_get(ctx);
    x = BN_CTX_get(ctx);
    y = BN_CTX_get(ctx);
    q = BN_CTX_get(ctx);
    if (!p || !a || !b || !x || !y || !q) {
        GOSTerr(GOST_F_FILL_GOST_EC_PARAMS, ERR_R_MALLOC_FAILURE);
        goto end;
    }

    if (!BN_hex2bn(&p, params->p)
        || !BN_hex2bn(&a, params->a)
        || !BN_hex2bn(&b, params->b)) {
        GOSTerr(GOST_F_FILL_GOST_EC_PARAMS, ERR_R_INTERNAL_ERROR);
        goto end;
    }

    grp = EC_GROUP_new_curve_GFp(p, a, b, ctx);
    if (!grp) {
        GOSTerr(GOST_F_FILL_GOST_EC_PARAMS, ERR_R_MALLOC_FAILURE);
        goto end;
    }

    P = EC_POINT_new(grp);
    if (!P) {
        GOSTerr(GOST_F_FILL_GOST_EC_PARAMS, ERR_R_MALLOC_FAILURE);
        goto end;
    }

    if (!BN_hex2bn(&x, params->x)
        || !BN_hex2bn(&y, params->y)
        || !EC_POINT_set_affine_coordinates_GFp(grp, P, x, y, ctx)
        || !BN_hex2bn(&q, params->q)) {
        GOSTerr(GOST_F_FILL_GOST_EC_PARAMS, ERR_R_INTERNAL_ERROR);
        goto end;
    }

    if (!EC_GROUP_set_generator(grp, P, q, NULL)) {
        GOSTerr(GOST_F_FILL_GOST_EC_PARAMS, ERR_R_INTERNAL_ERROR);
        goto end;
    }
    EC_GROUP_set_curve_name(grp, params->nid);
    if (!EC_KEY_set_group(eckey, grp)) {
        GOSTerr(GOST_F_FILL_GOST_EC_PARAMS, ERR_R_INTERNAL_ERROR);
        goto end;
    }
    ok = 1;
 end:
    if (P)
        EC_POINT_free(P);
    if (grp)
        EC_GROUP_free(grp);
    BN_CTX_end(ctx);
    BN_CTX_free(ctx);
    return ok;
}
Beispiel #27
0
int
process_peer_commit (pwd_session_t *sess, uint8_t *commit, BN_CTX *bnctx)
{
    uint8_t *ptr;
    BIGNUM *x = NULL, *y = NULL, *cofactor = NULL;
    EC_POINT *K = NULL, *point = NULL;
    int res = 1;

    if (((sess->peer_scalar = BN_new()) == NULL) ||
	((sess->k = BN_new()) == NULL) ||
	((cofactor = BN_new()) == NULL) ||
	((x = BN_new()) == NULL) ||
	((y = BN_new()) == NULL) ||
	((point = EC_POINT_new(sess->group)) == NULL) ||
	((K = EC_POINT_new(sess->group)) == NULL) ||
	((sess->peer_element = EC_POINT_new(sess->group)) == NULL)) {
	DEBUG2("pwd: failed to allocate room to process peer's commit");
	goto fin;
    }

    if (!EC_GROUP_get_cofactor(sess->group, cofactor, NULL)) {
	DEBUG2("pwd: unable to get group co-factor");
	goto fin;
    }

    /* element, x then y, followed by scalar */
    ptr = (uint8_t *)commit;
    BN_bin2bn(ptr, BN_num_bytes(sess->prime), x);
    ptr += BN_num_bytes(sess->prime);
    BN_bin2bn(ptr, BN_num_bytes(sess->prime), y);
    ptr += BN_num_bytes(sess->prime);
    BN_bin2bn(ptr, BN_num_bytes(sess->order), sess->peer_scalar);
    if (!EC_POINT_set_affine_coordinates_GFp(sess->group,
					     sess->peer_element, x, y,
					     bnctx)) {
	DEBUG2("pwd: unable to get coordinates of peer's element");
	goto fin;
    }

    /* check to ensure peer's element is not in a small sub-group */
    if (BN_cmp(cofactor, BN_value_one())) {
	if (!EC_POINT_mul(sess->group, point, NULL,
			  sess->peer_element, cofactor, NULL)) {
	    DEBUG2("pwd: unable to multiply element by co-factor");
	    goto fin;
	}
	if (EC_POINT_is_at_infinity(sess->group, point)) {
	    DEBUG2("pwd: peer's element is in small sub-group");
	    goto fin;
	}
    }

    /* compute the shared key, k */
    if ((!EC_POINT_mul(sess->group, K, NULL, sess->pwe,
		       sess->peer_scalar, bnctx)) ||
	(!EC_POINT_add(sess->group, K, K, sess->peer_element,
		       bnctx)) ||
	(!EC_POINT_mul(sess->group, K, NULL, K, sess->private_value,
		       bnctx))) {
	DEBUG2("pwd: unable to compute shared key, k");
	goto fin;
    }

    /* ensure that the shared key isn't in a small sub-group */
    if (BN_cmp(cofactor, BN_value_one())) {
	if (!EC_POINT_mul(sess->group, K, NULL, K, cofactor,
			  NULL)) {
	    DEBUG2("pwd: unable to multiply k by co-factor");
	    goto fin;
	}
    }

    /*
     * This check is strictly speaking just for the case above where
     * co-factor > 1 but it was suggested that even though this is probably
     * never going to happen it is a simple and safe check "just to be
     * sure" so let's be safe.
     */
    if (EC_POINT_is_at_infinity(sess->group, K)) {
	DEBUG2("pwd: k is point-at-infinity!");
	goto fin;
    }
    if (!EC_POINT_get_affine_coordinates_GFp(sess->group, K, sess->k,
					     NULL, bnctx)) {
	DEBUG2("pwd: unable to get shared secret from K");
	goto fin;
    }
    res = 0;

  fin:
    EC_POINT_free(K);
    EC_POINT_free(point);
    BN_free(cofactor);
    BN_free(x);
    BN_free(y);

    return res;
}
Beispiel #28
0
static LUA_FUNCTION(openssl_pkey_new)
{
  EVP_PKEY *pkey = NULL;
  const char* alg = "rsa";

  if (lua_isnoneornil(L, 1) || lua_isstring(L, 1))
  {
    alg = luaL_optstring(L, 1, alg);

    if (strcasecmp(alg, "rsa") == 0)
    {
      int bits = luaL_optint(L, 2, 1024);
      int e = luaL_optint(L, 3, 65537);
      RSA* rsa = RSA_new();

      BIGNUM *E = BN_new();
      BN_set_word(E, e);
      if (RSA_generate_key_ex(rsa, bits, E, NULL))
      {
        pkey = EVP_PKEY_new();
        EVP_PKEY_assign_RSA(pkey, rsa);
      }
      else
        RSA_free(rsa);
      BN_free(E);
    }
    else if (strcasecmp(alg, "dsa") == 0)
    {
      int bits = luaL_optint(L, 2, 1024);
      size_t seed_len = 0;
      const char* seed = luaL_optlstring(L, 3, NULL, &seed_len);

      DSA *dsa = DSA_new();
      if (DSA_generate_parameters_ex(dsa, bits, (byte*)seed, seed_len, NULL, NULL, NULL)
          && DSA_generate_key(dsa))
      {
        pkey = EVP_PKEY_new();
        EVP_PKEY_assign_DSA(pkey, dsa);
      }
      else
        DSA_free(dsa);
    }
    else if (strcasecmp(alg, "dh") == 0)
    {
      int bits = luaL_optint(L, 2, 512);
      int generator = luaL_optint(L, 3, 2);

      DH* dh = DH_new();
      if (DH_generate_parameters_ex(dh, bits, generator, NULL))
      {
        if (DH_generate_key(dh))
        {
          pkey = EVP_PKEY_new();
          EVP_PKEY_assign_DH(pkey, dh);
        }
        else
          DH_free(dh);
      }
      else
        DH_free(dh);
    }
#ifndef OPENSSL_NO_EC
    else if (strcasecmp(alg, "ec") == 0)
    {
      EC_KEY *ec = NULL;
      EC_GROUP *group = openssl_get_ec_group(L, 2, 3, 4);
      if (!group)
        luaL_error(L, "failed to get ec_group object");
      ec = EC_KEY_new();
      if (ec)
      {
        EC_KEY_set_group(ec, group);
        EC_GROUP_free(group);
        if (EC_KEY_generate_key(ec))
        {
          pkey = EVP_PKEY_new();
          EVP_PKEY_assign_EC_KEY(pkey, ec);
        }
        else
          EC_KEY_free(ec);
      }
      else
        EC_GROUP_free(group);

    }
#endif
    else
    {
      luaL_error(L, "not support %s!!!!", alg);
    }
  }
  else if (lua_istable(L, 1))
  {
    lua_getfield(L, 1, "alg");
    alg = luaL_optstring(L, -1, alg);
    lua_pop(L, 1);
    if (strcasecmp(alg, "rsa") == 0)
    {
      pkey = EVP_PKEY_new();
      if (pkey)
      {
        RSA *rsa = RSA_new();
        if (rsa)
        {
          OPENSSL_PKEY_SET_BN(1, rsa, n);
          OPENSSL_PKEY_SET_BN(1, rsa, e);
          OPENSSL_PKEY_SET_BN(1, rsa, d);
          OPENSSL_PKEY_SET_BN(1, rsa, p);
          OPENSSL_PKEY_SET_BN(1, rsa, q);
          OPENSSL_PKEY_SET_BN(1, rsa, dmp1);
          OPENSSL_PKEY_SET_BN(1, rsa, dmq1);
          OPENSSL_PKEY_SET_BN(1, rsa, iqmp);
          if (rsa->n)
          {
            if (!EVP_PKEY_assign_RSA(pkey, rsa))
            {
              EVP_PKEY_free(pkey);
              pkey = NULL;
            }
          }
        }
      }
    }
    else if (strcasecmp(alg, "dsa") == 0)
    {
      pkey = EVP_PKEY_new();
      if (pkey)
      {
        DSA *dsa = DSA_new();
        if (dsa)
        {
          OPENSSL_PKEY_SET_BN(-1, dsa, p);
          OPENSSL_PKEY_SET_BN(-1, dsa, q);
          OPENSSL_PKEY_SET_BN(-1, dsa, g);
          OPENSSL_PKEY_SET_BN(-1, dsa, priv_key);
          OPENSSL_PKEY_SET_BN(-1, dsa, pub_key);
          if (dsa->p && dsa->q && dsa->g)
          {
            if (!dsa->priv_key && !dsa->pub_key)
            {
              DSA_generate_key(dsa);
            }
            if (!EVP_PKEY_assign_DSA(pkey, dsa))
            {
              EVP_PKEY_free(pkey);
              pkey = NULL;
            }
          }
        }
      }
    }
    else if (strcasecmp(alg, "dh") == 0)
    {

      pkey = EVP_PKEY_new();
      if (pkey)
      {
        DH *dh = DH_new();
        if (dh)
        {
          OPENSSL_PKEY_SET_BN(-1, dh, p);
          OPENSSL_PKEY_SET_BN(-1, dh, g);
          OPENSSL_PKEY_SET_BN(-1, dh, priv_key);
          OPENSSL_PKEY_SET_BN(-1, dh, pub_key);
          if (dh->p && dh->g)
          {
            if (!dh->pub_key)
            {
              DH_generate_key(dh);
            }
            if (!EVP_PKEY_assign_DH(pkey, dh))
            {
              EVP_PKEY_free(pkey);
              pkey = NULL;
            }
          }
        }
      }
    }
    else if (strcasecmp(alg, "ec") == 0)
    {
      BIGNUM *d = NULL;
      BIGNUM *x = NULL;
      BIGNUM *y = NULL;
      BIGNUM *z = NULL;
      EC_GROUP *group = NULL;

      lua_getfield(L, -1, "ec_name");
      lua_getfield(L, -2, "param_enc");
      lua_getfield(L, -3, "conv_form");
      group = openssl_get_ec_group(L, -3, -2, -1);
      lua_pop(L, 3);
      if (!group)
      {
        luaL_error(L, "get openssl.ec_group fail");
      }

      EC_GET_FIELD(d);
      EC_GET_FIELD(x);
      EC_GET_FIELD(y);
      EC_GET_FIELD(z);


      pkey = EVP_PKEY_new();
      if (pkey)
      {
        EC_KEY *ec = EC_KEY_new();
        if (ec)
        {
          EC_KEY_set_group(ec, group);
          if (d)
            EC_KEY_set_private_key(ec, d);
          if (x != NULL && y != NULL)
          {
            EC_POINT *pnt = EC_POINT_new(group);
            if (z == NULL)
              EC_POINT_set_affine_coordinates_GFp(group, pnt, x, y, NULL);
            else
              EC_POINT_set_Jprojective_coordinates_GFp(group, pnt, x, y, z, NULL);

            EC_KEY_set_public_key(ec, pnt);
          }

          if (!EVP_PKEY_assign_EC_KEY(pkey, ec))
          {
            EC_KEY_free(ec);
            EVP_PKEY_free(pkey);
            pkey = NULL;
          }
          if (d && !EC_KEY_check_key(ec))
          {
            EC_KEY_generate_key_part(ec);
          }
        }
      }
    }
  }

  if (pkey)
  {
    PUSH_OBJECT(pkey, "openssl.evp_pkey");
    return 1;
  }
  return 0;

}
int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *group,
                                             EC_POINT *point, const BIGNUM *x_,
                                             int y_bit, BN_CTX *ctx) {
  BN_CTX *new_ctx = NULL;
  BIGNUM *tmp1, *tmp2, *x, *y;
  int ret = 0;

  ERR_clear_error();

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

  y_bit = (y_bit != 0);

  BN_CTX_start(ctx);
  tmp1 = BN_CTX_get(ctx);
  tmp2 = BN_CTX_get(ctx);
  x = BN_CTX_get(ctx);
  y = BN_CTX_get(ctx);
  if (y == NULL) {
    goto err;
  }

  /* Recover y.  We have a Weierstrass equation
   *     y^2 = x^3 + a*x + b,
   * so  y  is one of the square roots of  x^3 + a*x + b. */

  /* tmp1 := x^3 */
  if (!BN_nnmod(x, x_, &group->field, ctx)) {
    goto err;
  }

  if (group->meth->field_decode == 0) {
    /* field_{sqr,mul} work on standard representation */
    if (!group->meth->field_sqr(group, tmp2, x_, ctx) ||
        !group->meth->field_mul(group, tmp1, tmp2, x_, ctx)) {
      goto err;
    }
  } else {
    if (!BN_mod_sqr(tmp2, x_, &group->field, ctx) ||
        !BN_mod_mul(tmp1, tmp2, x_, &group->field, ctx)) {
      goto err;
    }
  }

  /* tmp1 := tmp1 + a*x */
  if (group->a_is_minus3) {
    if (!BN_mod_lshift1_quick(tmp2, x, &group->field) ||
        !BN_mod_add_quick(tmp2, tmp2, x, &group->field) ||
        !BN_mod_sub_quick(tmp1, tmp1, tmp2, &group->field)) {
      goto err;
    }
  } else {
    if (group->meth->field_decode) {
      if (!group->meth->field_decode(group, tmp2, &group->a, ctx) ||
          !BN_mod_mul(tmp2, tmp2, x, &group->field, ctx)) {
        goto err;
      }
    } else {
      /* field_mul works on standard representation */
      if (!group->meth->field_mul(group, tmp2, &group->a, x, ctx)) {
        goto err;
      }
    }

    if (!BN_mod_add_quick(tmp1, tmp1, tmp2, &group->field)) {
      goto err;
    }
  }

  /* tmp1 := tmp1 + b */
  if (group->meth->field_decode) {
    if (!group->meth->field_decode(group, tmp2, &group->b, ctx) ||
        !BN_mod_add_quick(tmp1, tmp1, tmp2, &group->field)) {
      goto err;
    }
  } else {
    if (!BN_mod_add_quick(tmp1, tmp1, &group->b, &group->field)) {
      goto err;
    }
  }

  if (!BN_mod_sqrt(y, tmp1, &group->field, ctx)) {
    unsigned long err = ERR_peek_last_error();

    if (ERR_GET_LIB(err) == ERR_LIB_BN &&
        ERR_GET_REASON(err) == BN_R_NOT_A_SQUARE) {
      ERR_clear_error();
      OPENSSL_PUT_ERROR(EC, ec_GFp_simple_set_compressed_coordinates, EC_R_INVALID_COMPRESSED_POINT);
    } else {
      OPENSSL_PUT_ERROR(EC, ec_GFp_simple_set_compressed_coordinates, ERR_R_BN_LIB);
    }
    goto err;
  }

  if (y_bit != BN_is_odd(y)) {
    if (BN_is_zero(y)) {
      int kron;

      kron = BN_kronecker(x, &group->field, ctx);
      if (kron == -2) {
        goto err;
      }

      if (kron == 1) {
        OPENSSL_PUT_ERROR(EC, ec_GFp_simple_set_compressed_coordinates,
                          EC_R_INVALID_COMPRESSION_BIT);
      } else {
        /* BN_mod_sqrt() should have cought this error (not a square) */
        OPENSSL_PUT_ERROR(EC, ec_GFp_simple_set_compressed_coordinates,
                          EC_R_INVALID_COMPRESSED_POINT);
      }
      goto err;
    }
    if (!BN_usub(y, &group->field, y)) {
      goto err;
    }
  }
  if (y_bit != BN_is_odd(y)) {
    OPENSSL_PUT_ERROR(EC, ec_GFp_simple_set_compressed_coordinates,
                      ERR_R_INTERNAL_ERROR);
    goto err;
  }

  if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx))
    goto err;

  ret = 1;

err:
  BN_CTX_end(ctx);
  if (new_ctx != NULL)
    BN_CTX_free(new_ctx);
  return ret;
}
Beispiel #30
0
cjose_jwk_t *cjose_jwk_create_EC_spec(
        const cjose_jwk_ec_keyspec *spec, cjose_err *err)
{
    cjose_jwk_t *   jwk = NULL;
    EC_KEY *        ec = NULL;
    EC_GROUP *      params = NULL;
    EC_POINT *      Q = NULL;
    BIGNUM *        bnD = NULL;
    BIGNUM *        bnX = NULL;
    BIGNUM *        bnY = NULL;

    if (!spec)
    {
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
        return NULL;
    }

    bool            hasPriv = (NULL != spec->d && 0 < spec->dlen);
    bool            hasPub = ((NULL != spec->x && 0 < spec->xlen) &&
                             (NULL != spec->y && 0 < spec->ylen));
    if (!hasPriv && !hasPub)
    {
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
        return NULL;
    }

    ec = EC_KEY_new_by_curve_name(spec->crv);
    if (NULL == ec)
    {
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
        goto create_EC_failed;
    }

    params = (EC_GROUP *)EC_KEY_get0_group(ec);
    if (NULL == params)
    {
        CJOSE_ERROR(err, CJOSE_ERR_NO_MEMORY);
        goto create_EC_failed;
    }

    // convert d from octet string to BIGNUM
    if (hasPriv)
    {
        bnD = BN_bin2bn(spec->d, spec->dlen, NULL);
        if (NULL == bnD)
        {
            CJOSE_ERROR(err, CJOSE_ERR_NO_MEMORY);
            goto create_EC_failed;
        }
        if (1 != EC_KEY_set_private_key(ec, bnD))
        {
            CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
            goto create_EC_failed;
        }

        // calculate public key from private
        Q = EC_POINT_new(params);
        if (NULL == Q)
        {
            CJOSE_ERROR(err, CJOSE_ERR_NO_MEMORY);
            goto create_EC_failed;
        }
        if (1 != EC_POINT_mul(params, Q, bnD, NULL, NULL, NULL))
        {
            CJOSE_ERROR(err, CJOSE_ERR_NO_MEMORY);
            goto create_EC_failed;
        }

        // public key is set below
        // ignore provided public key!
        hasPub = false;
    }
    if (hasPub)
    {
        Q = EC_POINT_new(params);
        if (NULL == Q)
        {
            CJOSE_ERROR(err, CJOSE_ERR_NO_MEMORY);
            goto create_EC_failed;
        }

        bnX = BN_bin2bn(spec->x, spec->xlen, NULL);
        bnY = BN_bin2bn(spec->y, spec->ylen, NULL);
        if (!bnX || !bnY)
        {
            CJOSE_ERROR(err, CJOSE_ERR_NO_MEMORY);
            goto create_EC_failed;
        }

        if (1 != EC_POINT_set_affine_coordinates_GFp(params, Q, bnX, bnY, NULL))
        {
            CJOSE_ERROR(err, CJOSE_ERR_NO_MEMORY);
            goto create_EC_failed;
        }
    }

    // always set the public key
    if (1 != EC_KEY_set_public_key(ec, Q))
    {
        CJOSE_ERROR(err, CJOSE_ERR_NO_MEMORY);
        goto create_EC_failed;
    }
    
    jwk = _EC_new(spec->crv, ec, err);
    if (!jwk)
    {
        goto create_EC_failed;
    }

    // jump to cleanup
    goto create_EC_cleanup;

    create_EC_failed:
    if (jwk)
    {
        cjose_get_dealloc()(jwk);
        jwk = NULL;
    }
    if (ec)
    {
        EC_KEY_free(ec);
        ec = NULL;
    }

    create_EC_cleanup:
    if (Q)
    {
        EC_POINT_free(Q);
        Q = NULL;
    }
    if (bnD)
    {
        BN_free(bnD);
        bnD = NULL;
    }
    if (bnX)
    {
        BN_free(bnX);
        bnX = NULL;
    }
    if (bnY)
    {
        BN_free(bnY);
        bnY = NULL;
    }

    return jwk;
}