I have X and Y as bignums. I create EVP_PKEY with this. I suspect that I have to do another step to indicate that I supplied X and Y and not a compressed public key. param_bld = OSSL_PARAM_BLD_new(); rc = getEcCurveString(&curveString, gets strings like prime256v1 irc = OSSL_PARAM_BLD_push_utf8_string(param_bld, OSSL_PKEY_PARAM_GROUP_NAME, curveString, 0); irc = OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_EC_PUB_X, x); irc = OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_EC_PUB_Y, y); params = OSSL_PARAM_BLD_to_param(param_bld); ctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL); irc = EVP_PKEY_fromdata_init(ctx); irc = EVP_PKEY_fromdata(ctx, evpPubkey, EVP_PKEY_PUBLIC_KEY, params); following that, this fails with irc = PEM_write_PUBKEY(pemFile, evpPubkey); ==88032== Invalid read of size 8 +=88032== at 0x4CB27F7: ec_point_is_compat (ec_local.h:328) ==88032== by 0x4CB2AB1: EC_POINT_point2oct (ec_oct.c:82) ==88032== by 0x4CA506F: i2o_ECPublicKey (ec_asn1.c:1158) ==88032== by 0x4E7B0D2: ec_spki_pub_to_der (encode_key2any.c:701) ==88032== by 0x4E79DBE: key_to_pubkey (encode_key2any.c:154) ==88032== by 0x4E7A490: key_to_spki_pem_pub_bio (encode_key2any.c:348) ==88032== by 0x4E7B9CA: key2any_encode (encode_key2any.c:1043) ==88032== by 0x4E7F539: ec_to_SubjectPublicKeyInfo_pem_encode (encode_key2any.c:1359) ==88032== by 0x4CF2C3F: encoder_process (encoder_lib.c:632) ==88032== by 0x4CF17AC: OSSL_ENCODER_to_bio (encoder_lib.c:63) ==88032== by 0x4CF1897: OSSL_ENCODER_to_fp (encoder_lib.c:85) ==88032== by 0x4D8BE33: PEM_write_PUBKEY (pem_all.c:226) point is null