Exemplo n.º 1
0
Arquivo: sign.c Projeto: dnstap/knot
/*!
 * \brief Decode ECDSA public key from RDATA and set it into EC key.
 * \note DNSKEY format for ECDSA is described in RFC 6605 section 4.
 */
static int ecdsa_set_public_key(const knot_binary_t *rdata, EC_KEY *ec_key)
{
	assert(rdata);
	assert(ec_key);

	const uint8_t *pubkey_data = NULL;
	size_t pubkey_size = 0;
	if (!any_dnskey_get_pubkey(rdata, &pubkey_data, &pubkey_size)) {
		return KNOT_EINVAL;
	}

	if (pubkey_size % 2 != 0) {
		return KNOT_EINVAL;
	}

	size_t param_size = pubkey_size / 2;
	const uint8_t *x_ptr = pubkey_data;
	const uint8_t *y_ptr = pubkey_data + param_size;

	BIGNUM *x = BN_bin2bn(x_ptr, param_size, NULL);
	BIGNUM *y = BN_bin2bn(y_ptr, param_size, NULL);

	int result = EC_KEY_set_public_key_affine_coordinates(ec_key, x, y);

	BN_free(x);
	BN_free(y);

	return result == 1 ? KNOT_EOK : KNOT_DNSSEC_EINVALID_KEY;
}
Exemplo n.º 2
0
static EC_KEY *self_test_ecdsa_key(void) {
  static const uint8_t kQx[] = {
      0xc8, 0x15, 0x61, 0xec, 0xf2, 0xe5, 0x4e, 0xde, 0xfe, 0x66, 0x17,
      0xdb, 0x1c, 0x7a, 0x34, 0xa7, 0x07, 0x44, 0xdd, 0xb2, 0x61, 0xf2,
      0x69, 0xb8, 0x3d, 0xac, 0xfc, 0xd2, 0xad, 0xe5, 0xa6, 0x81,
  };
  static const uint8_t kQy[] = {
      0xe0, 0xe2, 0xaf, 0xa3, 0xf9, 0xb6, 0xab, 0xe4, 0xc6, 0x98, 0xef,
      0x64, 0x95, 0xf1, 0xbe, 0x49, 0xa3, 0x19, 0x6c, 0x50, 0x56, 0xac,
      0xb3, 0x76, 0x3f, 0xe4, 0x50, 0x7e, 0xec, 0x59, 0x6e, 0x88,
  };
  static const uint8_t kD[] = {
      0xc6, 0xc1, 0xaa, 0xda, 0x15, 0xb0, 0x76, 0x61, 0xf8, 0x14, 0x2c,
      0x6c, 0xaf, 0x0f, 0xdb, 0x24, 0x1a, 0xff, 0x2e, 0xfe, 0x46, 0xc0,
      0x93, 0x8b, 0x74, 0xf2, 0xbc, 0xc5, 0x30, 0x52, 0xb0, 0x77,
  };

  EC_KEY *ec_key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
  BIGNUM *qx = BN_bin2bn(kQx, sizeof(kQx), NULL);
  BIGNUM *qy = BN_bin2bn(kQy, sizeof(kQy), NULL);
  BIGNUM *d = BN_bin2bn(kD, sizeof(kD), NULL);
  if (ec_key == NULL || qx == NULL || qy == NULL || d == NULL ||
      !EC_KEY_set_public_key_affine_coordinates(ec_key, qx, qy) ||
      !EC_KEY_set_private_key(ec_key, d)) {
    EC_KEY_free(ec_key);
    ec_key = NULL;
  }

  BN_free(qx);
  BN_free(qy);
  BN_free(d);
  return ec_key;
}
Exemplo n.º 3
0
int FIPS_selftest_ecdsa()
	{
	EC_KEY *ec = NULL;
	BIGNUM *x = NULL, *y = NULL, *d = NULL;
	EVP_PKEY pk;
	int rv = 0;
	size_t i;

	for (i = 0; i < sizeof(test_ec_data)/sizeof(EC_SELFTEST_DATA); i++)
		{
		EC_SELFTEST_DATA *ecd = test_ec_data + i;

		x = BN_bin2bn(ecd->x, ecd->xlen, x);
		y = BN_bin2bn(ecd->y, ecd->ylen, y);
		d = BN_bin2bn(ecd->d, ecd->dlen, d);

		if (!x || !y || !d)
			goto err;

		ec = EC_KEY_new_by_curve_name(ecd->curve);
		if (!ec)
			goto err;

		if (!EC_KEY_set_public_key_affine_coordinates(ec, x, y))
			goto err;

		if (!EC_KEY_set_private_key(ec, d))
			goto err;

		pk.type = EVP_PKEY_EC;
		pk.pkey.ec = ec;

		if (!fips_pkey_signature_test(FIPS_TEST_SIGNATURE, &pk, NULL, 0,
						NULL, 0, EVP_sha512(), 0,
						ecd->name))
			goto err;
		EC_KEY_free(ec);
		ec = NULL;
		}

	rv = 1;

	err:

	if (x)
		BN_clear_free(x);
	if (y)
		BN_clear_free(y);
	if (d)
		BN_clear_free(d);
	if (ec)
		EC_KEY_free(ec);

	return rv;

	}
Exemplo n.º 4
0
openssl::Key BackendOpenSsl::internal_public_key(const ecdsa256::PublicKey& generic) const
{
    openssl::Key key(NID_X9_62_prime256v1);
    openssl::BigNumber x(generic.x);
    openssl::BigNumber y(generic.y);
    EC_KEY_set_public_key_affine_coordinates(key, x, y);

    openssl::check(EC_KEY_check_key(key));
    return key;
}
Exemplo n.º 5
0
Handle<ScopedEVP_PKEY> JwkEc::To(int &key_type) {
	LOG_FUNC();

	LOG_INFO("Check key_type");
	if (!(key_type == NODESSL_KT_PRIVATE || key_type == NODESSL_KT_PUBLIC)) {
		THROW_ERROR("Wrong value of key_type");
	}

	LOG_INFO("import EC from JWK");
	ScopedEC_KEY ec_key(EC_KEY_new());

	LOG_INFO("set public key");
	ScopedEC_GROUP group(EC_GROUP_new_by_curve_name(this->crv));
	if (group.isEmpty()) {
		THROW_OPENSSL("EC_GROUP_new_by_curve_name");
	}

	EC_KEY_set_group(ec_key.Get(), group.Get());

	ScopedBIGNUM x(BN_dup(this->x.Get()));
	ScopedBIGNUM y(BN_dup(this->y.Get()));

	if (EC_KEY_set_public_key_affine_coordinates(ec_key.Get(), x.Get(), y.Get()) != 1) {
		THROW_OPENSSL("EC_KEY_set_public_key_affine_coordinates");
	}
	x.unref();
	y.unref();
	if (key_type == NODESSL_KT_PRIVATE) {
		LOG_INFO("set private key");

		ScopedBIGNUM d(BN_dup(this->d.Get()));
		if (EC_KEY_set_private_key(ec_key.Get(), d.Get()) != 1) {
			THROW_OPENSSL("EC_KEY_set_private_key");
		}
		d.unref();
	}

	LOG_INFO("set internal key");
	Handle<ScopedEVP_PKEY> new_key(new ScopedEVP_PKEY(EVP_PKEY_new()));
	EVP_PKEY_assign_EC_KEY(new_key->Get(), ec_key.Get());
	ec_key.unref();
	
	return new_key;
}
Exemplo n.º 6
0
static int PKV(FILE *in, FILE *out)
{

    char buf[2048], lbuf[2048];
    char *keyword, *value;
    int curve_nid = NID_undef;
    BIGNUM *Qx = NULL, *Qy = NULL;
    EC_KEY *key = NULL;
    while (fgets(buf, sizeof buf, in) != NULL) {
        fputs(buf, out);
        if (*buf == '[' && buf[2] == '-') {
            curve_nid = elookup_curve(buf, lbuf, NULL);
            if (curve_nid == NID_undef)
                return 0;

        }
        if (!parse_line(&keyword, &value, lbuf, buf))
            continue;
        if (!strcmp(keyword, "Qx")) {
            if (!do_hex2bn(&Qx, value)) {
                fprintf(stderr, "Invalid Qx value\n");
                return 0;
            }
        }
        if (!strcmp(keyword, "Qy")) {
            int rv;
            if (!do_hex2bn(&Qy, value)) {
                fprintf(stderr, "Invalid Qy value\n");
                return 0;
            }
            key = EC_KEY_new_by_curve_name(curve_nid);
            no_err = 1;
            rv = EC_KEY_set_public_key_affine_coordinates(key, Qx, Qy);
            no_err = 0;
            EC_KEY_free(key);
            fprintf(out, "Result = %s" RESP_EOL, rv ? "P" : "F");
        }

    }
    BN_free(Qx);
    BN_free(Qy);
    return 1;
}
Exemplo n.º 7
0
SEXP R_ecdsa_pubkey_build(SEXP x, SEXP y, SEXP nist){
#ifndef OPENSSL_NO_EC
  int nid = my_nist2nid(CHAR(STRING_ELT(nist, 0)));
  bail(nid);
  EC_KEY *pubkey = EC_KEY_new_by_curve_name(nid);
  EC_KEY_set_asn1_flag(pubkey, OPENSSL_EC_NAMED_CURVE);
  if(!EC_KEY_set_public_key_affine_coordinates(pubkey, new_bignum_from_r(x), new_bignum_from_r(y)))
    error("Failed to construct EC key. Perhaps invalid point or curve.");
  unsigned char *buf = NULL;
  int len = i2d_EC_PUBKEY(pubkey, &buf);
  bail(len);
  EC_KEY_free(pubkey);
  SEXP res = allocVector(RAWSXP, len);
  memcpy(RAW(res), buf, len);
  OPENSSL_free(buf);
  return res;
#else //OPENSSL_NO_EC
  Rf_error("OpenSSL has been configured without EC support");
#endif //OPENSSL_NO_EC
}
Exemplo n.º 8
0
jlong Java_org_keysupport_provider_ECDSASignature_jniVerifyInit(JNIEnv *env,
		jobject obj, jint jcid, jbyteArray jx, jbyteArray jy) {

//	LOGD("entering ECDSASignature_jniVerifyInit");

	EC_Ctx *ec = 0;
	BIGNUM *x, *y;

	if (!(ec = (EC_Ctx *) calloc(sizeof(EC_Ctx), 1))) {
		throw_exception(env, "java/lang/RuntimeException", "allocating EC_Ctx");
		destroy_ec_ctx(ec);
		return 0;
	}
	if (!(ec->ec = EC_KEY_new_by_curve_name(jcid))) {
		throw_exception(env, "java/lang/RuntimeException", "allocating EC_KEY");
		destroy_ec_ctx(ec);
		return 0;
	}
	if (!jba_to_bigint(env, &x, jx)) {
		throw_exception(env, "java/lang/RuntimeException", "importing affine coordinate x");
		destroy_ec_ctx(ec);
		return 0;
	}
	if (!jba_to_bigint(env, &y, jy)) {
		throw_exception(env, "java/lang/RuntimeException", "importing affine coordinate y");
		destroy_ec_ctx(ec);
		return 0;
	}
	if (!(EC_KEY_set_public_key_affine_coordinates(ec->ec, x, y))) {
		LOGE("Failed to set EC_KEY affine coordinates");
		throw_exception(env, "java/lang/RuntimeException", "setting EC_KEY affine coordinates");
		destroy_ec_ctx(ec);
		return 0;
	}

//	LOGD("leaving ECDSASignature_jniVerifyInit");

	return ((long) ec);

}
Exemplo n.º 9
0
/*
 * verify EC signature on JWT
 */
static apr_byte_t apr_jws_verify_ec(apr_pool_t *pool, apr_jwt_t *jwt,
                                    apr_jwk_t *jwk, apr_jwt_error_t *err) {

    int nid = apr_jws_ec_alg_to_curve(jwt->header.alg);
    if (nid == -1) {
        apr_jwt_error(err,
                      "no OpenSSL Elliptic Curve identifier found for algorithm \"%s\"",
                      jwt->header.alg);
        return FALSE;
    }

    EC_GROUP *curve = EC_GROUP_new_by_curve_name(nid);
    if (curve == NULL) {
        apr_jwt_error(err,
                      "no OpenSSL Elliptic Curve found for algorithm \"%s\"",
                      jwt->header.alg);
        return FALSE;
    }

    apr_byte_t rc = FALSE;

    /* get the OpenSSL digest function */
    const EVP_MD *digest = NULL;
    if ((digest = apr_jws_crypto_alg_to_evp(pool, jwt->header.alg, err)) == NULL)
        return FALSE;

    EVP_MD_CTX ctx;
    EVP_MD_CTX_init(&ctx);

    EC_KEY * pubkey = EC_KEY_new();
    EC_KEY_set_group(pubkey, curve);

    BIGNUM * x = BN_new();
    BIGNUM * y = BN_new();

    BN_bin2bn(jwk->key.ec->x, jwk->key.ec->x_len, x);
    BN_bin2bn(jwk->key.ec->y, jwk->key.ec->y_len, y);

    if (!EC_KEY_set_public_key_affine_coordinates(pubkey, x, y)) {
        apr_jwt_error_openssl(err, "EC_KEY_set_public_key_affine_coordinates");
        return FALSE;
    }

    EVP_PKEY* pEcKey = EVP_PKEY_new();
    if (!EVP_PKEY_assign_EC_KEY(pEcKey, pubkey)) {
        pEcKey = NULL;
        apr_jwt_error_openssl(err, "EVP_PKEY_assign_EC_KEY");
        goto end;
    }

    ctx.pctx = EVP_PKEY_CTX_new(pEcKey, NULL);

    if (!EVP_PKEY_verify_init(ctx.pctx)) {
        apr_jwt_error_openssl(err, "EVP_PKEY_verify_init");
        goto end;
    }
    if (!EVP_VerifyInit_ex(&ctx, digest, NULL)) {
        apr_jwt_error_openssl(err, "EVP_VerifyInit_ex");
        goto end;
    }
    if (!EVP_VerifyUpdate(&ctx, jwt->message, strlen(jwt->message))) {
        apr_jwt_error_openssl(err, "EVP_VerifyUpdate");
        goto end;
    }
    if (!EVP_VerifyFinal(&ctx, (const unsigned char *) jwt->signature.bytes,
                         jwt->signature.length, pEcKey)) {
        apr_jwt_error_openssl(err, "wrong key? EVP_VerifyFinal");
        goto end;
    }

    rc = TRUE;

end:

    if (pEcKey) {
        EVP_PKEY_free(pEcKey);
    } else if (pubkey) {
        EC_KEY_free(pubkey);
    }
    EVP_MD_CTX_cleanup(&ctx);

    return rc;
}
Exemplo n.º 10
0
int FIPS_selftest_ecdh(void)
{
    EC_KEY *ec1 = NULL, *ec2 = NULL;
    const EC_POINT *ecp = NULL;
    BIGNUM *x = NULL, *y = NULL, *d = NULL;
    unsigned char *ztmp = NULL;
    int rv = 1;
    size_t i;

    for (i = 0; i < sizeof(test_ecdh_data) / sizeof(ECDH_SELFTEST_DATA); i++) {
        ECDH_SELFTEST_DATA *ecd = test_ecdh_data + i;
        if (!fips_post_started(FIPS_TEST_ECDH, ecd->curve, 0))
            continue;
        ztmp = OPENSSL_malloc(ecd->zlen);

        x = BN_bin2bn(ecd->x1, ecd->x1len, x);
        y = BN_bin2bn(ecd->y1, ecd->y1len, y);
        d = BN_bin2bn(ecd->d1, ecd->d1len, d);

        if (!x || !y || !d || !ztmp) {
            rv = -1;
            goto err;
        }

        ec1 = EC_KEY_new_by_curve_name(ecd->curve);
        if (!ec1) {
            rv = -1;
            goto err;
        }
        EC_KEY_set_flags(ec1, EC_FLAG_COFACTOR_ECDH);

        if (!EC_KEY_set_public_key_affine_coordinates(ec1, x, y)) {
            rv = -1;
            goto err;
        }

        if (!EC_KEY_set_private_key(ec1, d)) {
            rv = -1;
            goto err;
        }

        x = BN_bin2bn(ecd->x2, ecd->x2len, x);
        y = BN_bin2bn(ecd->y2, ecd->y2len, y);

        if (!x || !y) {
            rv = -1;
            goto err;
        }

        ec2 = EC_KEY_new_by_curve_name(ecd->curve);
        if (!ec2) {
            rv = -1;
            goto err;
        }
        EC_KEY_set_flags(ec1, EC_FLAG_COFACTOR_ECDH);

        if (!EC_KEY_set_public_key_affine_coordinates(ec2, x, y)) {
            rv = -1;
            goto err;
        }

        ecp = EC_KEY_get0_public_key(ec2);
        if (!ecp) {
            rv = -1;
            goto err;
        }

        if (!ECDH_compute_key(ztmp, ecd->zlen, ecp, ec1, 0)) {
            rv = -1;
            goto err;
        }

        if (!fips_post_corrupt(FIPS_TEST_ECDH, ecd->curve, NULL))
            ztmp[0] ^= 0x1;

        if (memcmp(ztmp, ecd->z, ecd->zlen)) {
            fips_post_failed(FIPS_TEST_ECDH, ecd->curve, 0);
            rv = 0;
        } else if (!fips_post_success(FIPS_TEST_ECDH, ecd->curve, 0))
            goto err;

        EC_KEY_free(ec1);
        ec1 = NULL;
        EC_KEY_free(ec2);
        ec2 = NULL;
        OPENSSL_free(ztmp);
        ztmp = NULL;
    }

 err:

    if (x)
        BN_clear_free(x);
    if (y)
        BN_clear_free(y);
    if (d)
        BN_clear_free(d);
    if (ec1)
        EC_KEY_free(ec1);
    if (ec2)
        EC_KEY_free(ec2);
    if (ztmp)
        OPENSSL_free(ztmp);

    return rv;

}
Exemplo n.º 11
0
// unsigned char *rgbHashData, 哈希数值
// unsigned char *rgbKeyPb, SM2公钥数据,Px Py 不含标志位 point_conversion_form_t
// unsigned char *rs 待验证的签名数据
unsigned char eccVerifySignature(unsigned char *rgbHashData, unsigned char *rgbKeyPb, unsigned char *rs)
{
	int ret = SM2_VERIFY_INNER_ERROR;
	EC_POINT *point = NULL;
	BN_CTX *ctx = NULL;
	BIGNUM *order = NULL;
	BIGNUM *e = NULL;
	BIGNUM *t = NULL;
	int i;

	EC_KEY *ec_key = EC_KEY_new_by_curve_name(NID_sm2p256v1);

	BIGNUM *x = BN_new();;
	BIGNUM *y = BN_new();;
	if (!BN_bin2bn(rgbKeyPb, 32, x)) {
		goto err;
	}
	if (!BN_bin2bn(rgbKeyPb + 32, 32, y)) {
		goto err;
	}
	if (!EC_KEY_set_public_key_affine_coordinates(ec_key, x, y)) {
		goto err;
	}
	const EC_POINT *pub_key = EC_KEY_get0_public_key(ec_key);

	BIGNUM *r= BN_new(), *s = BN_new();
	BN_bin2bn(rs, 32, r);
	BN_bin2bn(rs + 32, 32, s);

	//// 相当于
	//EC_KEY *ret = EC_KEY_new();
	EC_GROUP *ec_group = EC_GROUP_new_by_curve_name(NID_sm2p256v1);

	ctx = BN_CTX_new();
	order = BN_new();
	e = BN_new();
	t = BN_new();

	if (!ctx || !order || !e || !t) {
		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
		goto err;
	}
	if (!EC_GROUP_get_order(ec_group, order, ctx)) {
		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
		goto err;
	}

	/* check r, s in [1, n-1] and r + s != 0 (mod n) */ 
	if (BN_is_zero(r) ||
		BN_is_negative(r) ||
		BN_ucmp(r, order) >= 0 || 
		BN_is_zero(s) ||
		BN_is_negative(s) || 
		BN_ucmp(s, order) >= 0) {

			ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_BAD_SIGNATURE);
			ret = 0;
			goto err;
	}

	/* check t = r + s != 0 */
	if (!BN_mod_add(t, r, s, order, ctx)) {
		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
		goto err;
	}
	if (BN_is_zero(t)) {
		ret = 0;
		goto err;
	}

	/* convert digest to e */
	i = BN_num_bits(order);
#if 0
	if (8 * dgstlen > i) {
		dgstlen = (i + 7)/8;
	}
#endif
	if (!BN_bin2bn(rgbHashData, 32, e)) {
		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
		goto err;
	}
#if 0
	if ((8 * dgstlen > i) && !BN_rshift(e, e, 8 - (i & 0x7))) {
		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
		goto err;
	}
#endif

	/* compute (x, y) = sG + tP, P is pub_key */
	if (!(point = EC_POINT_new(ec_group))) {
		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
		goto err;
	}
	if (!EC_POINT_mul(ec_group, point, s, pub_key, t, ctx)) {
		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
		goto err;
	}
	if (EC_METHOD_get_field_type(EC_GROUP_method_of(ec_group)) == NID_X9_62_prime_field) {
		if (!EC_POINT_get_affine_coordinates_GFp(ec_group, point, t, NULL, ctx)) {
			ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
			goto err;
		}
	} else /* NID_X9_62_characteristic_two_field */ { 
		if (!EC_POINT_get_affine_coordinates_GF2m(ec_group, point, t, NULL, ctx)) {
			ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
			goto err;
		}
	}
	if (!BN_nnmod(t, t, order, ctx)) {
		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
		goto err;
	}

	/* check (sG + tP).x + e  == sig.r */
	if (!BN_mod_add(t, t, e, order, ctx)) {
		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
		goto err;
	}
	if (BN_ucmp(t, r) == 0) {
		ret = SM2_VERIFY_SUCCESS;
	} else {
		ret = SM2_VERIFY_FAILED;
	}

err:
	if (point) EC_POINT_free(point);
	if (order) BN_free(order);
	if (e) BN_free(e);
	if (t) BN_free(t);
	if (ctx) BN_CTX_free(ctx);
	return 0;
}
Exemplo n.º 12
0
static EVP_PKEY *ssh_nistp_line_to_key(char *line)
{
	EVP_PKEY *key;
	EC_KEY *ec_key;
	BIGNUM *x;
	BIGNUM *y;

	unsigned char decoded[OPENSSH_LINE_MAX];
	int len;
	int flen;

	char *b, *c;
	int i;
	int nid;

	/* check allowed key size */
	if (strncmp(line + 16, "256", 3) == 0)
		flen = 32, nid = NID_X9_62_prime256v1;
	else if (strncmp(line + 16, "384", 3) == 0)
		flen = 48, nid = NID_secp384r1;
	else if (strncmp(line + 16, "521", 3) == 0)
		flen = 66, nid = NID_secp521r1;
	else
		return NULL;

	/* find the mime-blob */
	b = line;

	if (!b)
		return NULL;

	/* find the first whitespace */
	while (*b && *b != ' ')
		b++;

	/* skip that whitespace */
	b++;

	/* find the end of the blob / comment */
	for (c = b; *c && *c != ' ' && 'c' != '\t' && *c != '\r'
	     && *c != '\n'; c++) ;

	*c = 0;

	/* decode binary data */
	if (sc_base64_decode(b, decoded, OPENSSH_LINE_MAX) < 0)
		return NULL;

	i = 0;
	/* get integer from blob */
	len =
	    (decoded[i] << 24) + (decoded[i + 1] << 16) +
	    (decoded[i + 2] << 8) + (decoded[i + 3]);
	i += 4;

	/* always check 'len' to get safe 'i' as index into 'decoded' array */
	if (len != 19)
		return NULL;
	/* check key type (must be same in decoded data and at line start) */
	if (strncmp((char *)&decoded[i], line, 19) != 0)
		return NULL;
	i += len;

	/* get integer from blob */
	len =
	    (decoded[i] << 24) + (decoded[i + 1] << 16) +
	    (decoded[i + 2] << 8) + (decoded[i + 3]);
	i += 4;

	/* check curve name - must match key type */
	if(len != 8)
		return NULL;
	if (strncmp((char *)&decoded[i], line + 11, 8) != 0)
		return NULL;
	i += len;

	/* get integer from blob */
	len =
	    (decoded[i] << 24) + (decoded[i + 1] << 16) +
	    (decoded[i + 2] << 8) + (decoded[i + 3]);
	i += 4;

	/* read public key (uncompressed point) */
	/* test if data length is corresponding to key size */
	if (len != 1 + flen * 2)
		return NULL;

	/* check uncompressed indicator */
	if (decoded[i] != 4 )
		return NULL;
	i++;

	/* create key */
	ec_key = EC_KEY_new_by_curve_name(nid);

	/* read point coordinates */
	x = BN_bin2bn(decoded + i, flen, NULL);
	i += flen;
	y = BN_bin2bn(decoded + i, flen, NULL);

	/* do error checking here: valid x, y, ec_key, point on curve.. */
	if (!EC_KEY_set_public_key_affine_coordinates(ec_key, x, y)) {
		EC_KEY_free(ec_key);
		BN_free(x);
		BN_free(y);
		return NULL;
	}

	key = EVP_PKEY_new();
	EVP_PKEY_assign_EC_KEY(key, ec_key);
	return key;
}
Exemplo n.º 13
0
int dnskey_build_pkey(struct rr_dnskey *rr)
{
    if (rr->pkey_built)
        return rr->pkey ? 1 : 0;

    rr->pkey_built = 1;

    if (algorithm_type(rr->algorithm) == ALG_RSA_FAMILY) {
        RSA *rsa;
        EVP_PKEY *pkey;
        unsigned int e_bytes;
        unsigned char *pk;
        int l;

        rsa = RSA_new();
        if (!rsa)
            goto done;

        pk = (unsigned char *)rr->pubkey.data;
        l = rr->pubkey.length;

        e_bytes = *pk++;
        l--;
        if (e_bytes == 0) {
            if (l < 2) /* public key is too short */
                goto done;
            e_bytes = (*pk++)  << 8;
            e_bytes += *pk++;
            l -= 2;
        }
        if (l < e_bytes) /* public key is too short */
            goto done;

        rsa->e = BN_bin2bn(pk, e_bytes, NULL);
        pk += e_bytes;
        l -= e_bytes;

        rsa->n = BN_bin2bn(pk, l, NULL);

        pkey = EVP_PKEY_new();
        if (!pkey)
            goto done;

        if (!EVP_PKEY_set1_RSA(pkey, rsa))
            goto done;

        rr->pkey = pkey;
    } else if (algorithm_type(rr->algorithm) == ALG_ECC_FAMILY) {
        EC_KEY *pubeckey;
        EVP_PKEY *pkey;
        unsigned char *pk;
        int l;
        BIGNUM *bn_x = NULL;
        BIGNUM *bn_y = NULL;

        if (rr->algorithm == ALG_ECDSAP256SHA256) {
            l = SHA256_DIGEST_LENGTH;
            pubeckey = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
        } else if (rr->algorithm == ALG_ECDSAP384SHA384) {
            l = SHA384_DIGEST_LENGTH;
            pubeckey = EC_KEY_new_by_curve_name(NID_secp384r1);
        } else {
            goto done;
        }

        if (!pubeckey)
            goto done;

        if (rr->pubkey.length != 2*l) {
            goto done;
        }

        pk = (unsigned char *)rr->pubkey.data;

        bn_x = BN_bin2bn(pk, l, NULL);
        bn_y = BN_bin2bn(&pk[l], l, NULL);

        if (1 != EC_KEY_set_public_key_affine_coordinates(pubeckey, bn_x, bn_y)) {
            goto done;
        }

        pkey = EVP_PKEY_new();
        if (!pkey)
            goto done;

        if (!EVP_PKEY_assign_EC_KEY(pkey, pubeckey))
            goto done;

        rr->pkey = pkey;
    }
done:
    if (!rr->pkey) {
        moan(rr->rr.file_name, rr->rr.line, "error building pkey");
    }
    return rr->pkey ? 1 : 0;
}
Exemplo n.º 14
0
static int SigVer(FILE *in, FILE *out)
{
    char buf[2048], lbuf[2048];
    char *keyword, *value;
    unsigned char *msg = NULL;
    int curve_nid = NID_undef;
    long mlen;
    BIGNUM *Qx = NULL, *Qy = NULL;
    EC_KEY *key = NULL;
    ECDSA_SIG sg, *sig = &sg;
    const EVP_MD *digest = NULL;
    sig->r = NULL;
    sig->s = NULL;
    while (fgets(buf, sizeof buf, in) != NULL) {
        fputs(buf, out);
        if (*buf == '[') {
            curve_nid = elookup_curve(buf, lbuf, &digest);
            if (curve_nid == NID_undef)
                return 0;
        }
        if (!parse_line(&keyword, &value, lbuf, buf))
            continue;
        if (!strcmp(keyword, "Msg")) {
            msg = hex2bin_m(value, &mlen);
            if (!msg) {
                fprintf(stderr, "Invalid Message\n");
                return 0;
            }
        }

        if (!strcmp(keyword, "Qx")) {
            if (!do_hex2bn(&Qx, value)) {
                fprintf(stderr, "Invalid Qx value\n");
                return 0;
            }
        }
        if (!strcmp(keyword, "Qy")) {
            if (!do_hex2bn(&Qy, value)) {
                fprintf(stderr, "Invalid Qy value\n");
                return 0;
            }
        }
        if (!strcmp(keyword, "R")) {
            if (!do_hex2bn(&sig->r, value)) {
                fprintf(stderr, "Invalid R value\n");
                return 0;
            }
        }
        if (!strcmp(keyword, "S")) {
            int rv;
            if (!do_hex2bn(&sig->s, value)) {
                fprintf(stderr, "Invalid S value\n");
                return 0;
            }
            key = EC_KEY_new_by_curve_name(curve_nid);
            rv = EC_KEY_set_public_key_affine_coordinates(key, Qx, Qy);

            if (rv != 1) {
                fprintf(stderr, "Error setting public key\n");
                return 0;
            }

            no_err = 1;
            rv = FIPS_ecdsa_verify(key, msg, mlen, digest, sig);
            EC_KEY_free(key);
            if (msg)
                OPENSSL_free(msg);
            no_err = 0;

            fprintf(out, "Result = %s" RESP_EOL, rv ? "P" : "F");
        }

    }
    if (sig->r)
        BN_free(sig->r);
    if (sig->s)
        BN_free(sig->s);
    if (Qx)
        BN_free(Qx);
    if (Qy)
        BN_free(Qy);
    return 1;
}
Exemplo n.º 15
0
/* Verify the signature on this transaction using the public key
 * prev_tx->dest_pubkey. The return value is:
 *  1 for successful verification;
 *  0 for failed verification;
 * -1 for any runtime error. */
int transaction_verify(struct transaction *tx, const struct transaction *prev_tx)
{
	unsigned char uint32_buf[4];
	SHA256_CTX sha;
	hash_output h;
	EC_KEY *pubkey;
	ECDSA_SIG *sig;
	BIGNUM *x, *y;
	int v, rc;

	pubkey = NULL;
	sig = NULL;
	x = NULL;
	y = NULL;

	SHA256_Init(&sha);
	serialize_uint32(uint32_buf, tx->height);
	SHA256_Update(&sha, uint32_buf, sizeof(uint32_buf));
	SHA256_Update(&sha, tx->prev_transaction_hash, sizeof(tx->prev_transaction_hash));
	SHA256_Update(&sha, tx->dest_pubkey.x, sizeof(tx->dest_pubkey.x));
	SHA256_Update(&sha, tx->dest_pubkey.y, sizeof(tx->dest_pubkey.y));
	SHA256_Final(h, &sha);

	x = BN_bin2bn(prev_tx->dest_pubkey.x, sizeof(prev_tx->dest_pubkey.x), NULL);
	if (x == NULL)
		goto err;
	y = BN_bin2bn(prev_tx->dest_pubkey.y, sizeof(prev_tx->dest_pubkey.y), NULL);
	if (y == NULL)
		goto err;

	pubkey = EC_KEY_new_by_curve_name(EC_GROUP_NID);
	if (pubkey == NULL)
		goto err;
	rc = EC_KEY_set_public_key_affine_coordinates(pubkey, x, y);
	if (rc != 1) {
		EC_KEY_free(pubkey);
		BN_free(x);
		BN_free(y);
		return 0;
	}

	BN_free(x);
	x = NULL;
	BN_free(y);
	y = NULL;

	sig = ECDSA_SIG_new();
	if (sig == NULL)
		goto err;

	sig->r = BN_bin2bn(tx->src_signature.r, sizeof(tx->src_signature.r), sig->r);
	if (sig->r == NULL)
		goto err;
	sig->s = BN_bin2bn(tx->src_signature.s, sizeof(tx->src_signature.s), sig->s);
	if (sig->s == NULL)
		goto err;

	v = ECDSA_do_verify(h, sizeof(h), sig, pubkey);

	EC_KEY_free(pubkey);
	ECDSA_SIG_free(sig);

	return v;

err:
	if (pubkey != NULL)
		EC_KEY_free(pubkey);
	if (sig != NULL)
		ECDSA_SIG_free(sig);
	if (x != NULL)
		BN_free(x);
	if (y != NULL)
		BN_free(y);

	return -1;
}
Exemplo n.º 16
0
void
ecdsa_sigverify(val_context_t * ctx,
                const u_char *data,
                size_t data_len,
                const val_dnskey_rdata_t * dnskey,
                const val_rrsig_rdata_t * rrsig,
                val_astatus_t * key_status, val_astatus_t * sig_status)
{
    char            buf[1028];
    size_t          buflen = 1024;
    u_char   sha_hash[MAX_DIGEST_LENGTH];
    EC_KEY   *eckey = NULL;
    BIGNUM *bn_x = NULL;
    BIGNUM *bn_y = NULL;
    ECDSA_SIG *ecdsa_sig;
    size_t   hashlen = 0;

    ecdsa_sig = ECDSA_SIG_new();
    memset(sha_hash, 0, sizeof(sha_hash));

    val_log(ctx, LOG_DEBUG,
            "ecdsa_sigverify(): parsing the public key...");

    if (rrsig->algorithm == ALG_ECDSAP256SHA256) {
        hashlen = SHA256_DIGEST_LENGTH; 
        SHA256(data, data_len, sha_hash);
        eckey = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); /* P-256 */
    } else if (rrsig->algorithm == ALG_ECDSAP384SHA384) {
        hashlen = SHA384_DIGEST_LENGTH; 
        SHA384(data, data_len, sha_hash);
        eckey = EC_KEY_new_by_curve_name(NID_secp384r1); /* P-384 */
    } 

    if (eckey == NULL) {
        val_log(ctx, LOG_INFO,
                "ecdsa_sigverify(): could not create key for ECDSA group.");
        *key_status = VAL_AC_INVALID_KEY;
        goto err;
    };

    /* 
     * contruct an EC_POINT from the "Q" field in the 
     * dnskey->public_key, dnskey->public_key_len
     */
    if (dnskey->public_key_len != 2*hashlen) {
        val_log(ctx, LOG_INFO,
                "ecdsa_sigverify(): dnskey length does not match expected size.");
        *key_status = VAL_AC_INVALID_KEY;
        goto err;
    }
    bn_x = BN_bin2bn(dnskey->public_key, hashlen, NULL);
    bn_y = BN_bin2bn(&dnskey->public_key[hashlen], hashlen, NULL);
    if (1 != EC_KEY_set_public_key_affine_coordinates(eckey, bn_x, bn_y)) {
        val_log(ctx, LOG_INFO,
                "ecdsa_sigverify(): Error associating ECSA structure with key.");
        *key_status = VAL_AC_INVALID_KEY;
        goto err;
    }


    val_log(ctx, LOG_DEBUG, "ecdsa_sigverify(): SHA hash = %s",
            get_hex_string(sha_hash, hashlen, buf, buflen));
    val_log(ctx, LOG_DEBUG,
            "ecdsa_sigverify(): verifying ECDSA signature...");

    /* 
     * contruct ECDSA signature from the "r" and "s" fileds in 
     * rrsig->signature, rrsig->signature_len
     */
    if (rrsig->signature_len != 2*hashlen) {
        val_log(ctx, LOG_INFO,
                "ecdsa_sigverify(): Signature length does not match expected size.");
        *sig_status = VAL_AC_RRSIG_VERIFY_FAILED;
        goto err;
    }

    ECDSA_SIG_set0(ecdsa_sig, BN_bin2bn(rrsig->signature, hashlen, NULL),
                   BN_bin2bn(&rrsig->signature[hashlen], hashlen, NULL));

    if (ECDSA_do_verify(sha_hash, hashlen, ecdsa_sig, eckey) == 1) {
        val_log(ctx, LOG_INFO, "ecdsa_sigverify(): returned SUCCESS");
        *sig_status = VAL_AC_RRSIG_VERIFIED;
    } else {
        val_log(ctx, LOG_INFO, "ecdsa_sigverify(): returned FAILURE");
        *sig_status = VAL_AC_RRSIG_VERIFY_FAILED;
    }

    /* Free all structures allocated */
err:
    if (ecdsa_sig)
        ECDSA_SIG_free(ecdsa_sig);
    if (bn_x)
        BN_free(bn_x);
    if (bn_y)
        BN_free(bn_y);
    if (eckey)
        EC_KEY_free(eckey);

    return;

}
Exemplo n.º 17
0
// unsigned char *pC      输出,密文
// unsigned char *pPxKey, unsigned char *pPyKey  公钥
// unsigned char *pM      明文
// unsigned long MLen     明文长度
unsigned char eccEncrypt(unsigned char *pC, 
						 unsigned char *pPxKey, unsigned char *pPyKey, 
						 unsigned char *pM, unsigned long MLen)
{
	// NID_sm2p256v1
	EC_KEY *ec_key = EC_KEY_new_by_curve_name(NID_sm2p256v1);
	//// 相当于
	//EC_KEY *ret = EC_KEY_new();
	EC_GROUP *ec_group = EC_GROUP_new_by_curve_name(NID_sm2p256v1);

	KDF_FUNC kdf = KDF_get_x9_63(EVP_sm3());;

	EC_POINT *point = NULL;
	//// 设置私钥
	//BIGNUM *d = NULL;
	//BN_hex2bn(&d, pPDKey);
	//EC_KEY_set_private_key(ec_key, d);
	int ret = 1;

	BIGNUM *x = BN_new();;
	BIGNUM *y = BN_new();;
	if (!BN_bin2bn(pPxKey, 32, x)) {
		goto end;
	}
	if (!BN_bin2bn(pPyKey, 32, y)) {
		goto end;
	}
	if (!EC_KEY_set_public_key_affine_coordinates(ec_key, x, y)) {
		goto end;
	}
	const EC_POINT *pub_key = EC_KEY_get0_public_key(ec_key);
	/* init ec domain parameters */
	BIGNUM *n = NULL;
	BIGNUM *h = NULL;
	BIGNUM *k = NULL;
	n = BN_new();
	h = BN_new();
	k = BN_new();
	BN_CTX *bn_ctx = NULL;
	bn_ctx = BN_CTX_new();
	if (!EC_GROUP_get_order(ec_group, n, bn_ctx)) {
		goto end;
	}
	if (!EC_GROUP_get_cofactor(ec_group, h, bn_ctx)) {
		goto end;
	}
	int nbytes = (EC_GROUP_get_degree(ec_group) + 7) / 8;

	EC_POINT *ec_point = EC_POINT_new(ec_group);
	point = EC_POINT_new(ec_group);
	unsigned char buf[(OPENSSL_ECC_MAX_FIELD_BITS + 7)/4 + 1];
	size_t len;
	char *ciphertext = (char *)OPENSSL_malloc(MLen);
	size_t ciphertext_size = MLen;
	do
	{
		/* A1: rand k in [1, n-1] */
		do {
			BN_rand_range(k, n);
		} while (BN_is_zero(k));

		/* A2: C1 = [k]G = (x1, y1) */
		if (!EC_POINT_mul(ec_group, ec_point, k, NULL, NULL, bn_ctx)) {
			goto end;
		}
#if 1
		if (!(len = EC_POINT_point2oct(ec_group, ec_point,
			POINT_CONVERSION_UNCOMPRESSED, buf, sizeof(buf), bn_ctx))) {
				goto end;
		}
		BN_bin2bn(buf, 65, n);
		printf(BN_bn2hex(n));
		printf("\n");
		printf(BN_bn2hex(k));
#endif
		/* A3: check [h]P_B != O */
		if (!EC_POINT_mul(ec_group, point, NULL, pub_key, h, bn_ctx)) {
			goto end;
		}
		if (EC_POINT_is_at_infinity(ec_group, point)) {
			goto end;
		}

		/* A4: compute ECDH [k]P_B = (x2, y2) */
		if (!EC_POINT_mul(ec_group, point, NULL, pub_key, k, bn_ctx)) {
			goto end;
		}
		if (!(len = EC_POINT_point2oct(ec_group, point,
			POINT_CONVERSION_UNCOMPRESSED, buf, sizeof(buf), bn_ctx))) {
				goto end;
		}
		OPENSSL_assert(len == nbytes * 2 + 1);

		/* A5: t = KDF(x2 || y2, klen) */
		kdf(buf + 1, len - 1, (unsigned char *)ciphertext, &ciphertext_size);

		// 防止全0
		size_t i = 0;
		for (i = 0; i < ciphertext_size; i++) {
			if (ciphertext[i]) {
				break;
			}
		}
		if (i == ciphertext_size) {
			continue;
		}
		break;
	} while (1);


	/* A6: C2 = M xor t */
	for (size_t i = 0; i < MLen; i++) {
		ciphertext[i] ^= pM[i];
	}

	unsigned char dgst[EVP_MAX_MD_SIZE];
	unsigned int dgstlen;
	EVP_MD_CTX *md_ctx = EVP_MD_CTX_create();
	if (1) {

		/* A7: C3 = Hash(x2 || M || y2) */
		if (!EVP_DigestInit_ex(md_ctx, EVP_sm3(), NULL)) {
			goto end;
		}
		if (!EVP_DigestUpdate(md_ctx, buf + 1, nbytes)) {
			goto end;
		}
		if (!EVP_DigestUpdate(md_ctx, pM, MLen)) {
			goto end;
		}
		if (!EVP_DigestUpdate(md_ctx, buf + 1 + nbytes, nbytes)) {
			goto end;
		}
		if (!EVP_DigestFinal_ex(md_ctx, dgst, &dgstlen)) {
			goto end;
		}
	}

	EC_POINT_point2oct(ec_group, point, POINT_CONVERSION_UNCOMPRESSED, pC, 65, NULL);
	memcpy(&pC[65], ciphertext, MLen);
	memcpy(&pC[65 + MLen], dgst, dgstlen);
ret = 0;
end:

	if (point) EC_POINT_free(point);
	if (n) BN_free(n);
	if (h) BN_free(h);
	if (k) BN_free(k);
	if (bn_ctx) BN_CTX_free(bn_ctx);
	if (md_ctx) EVP_MD_CTX_destroy(md_ctx);

	return ret;
}