/* * Get EC key material and stash pointer in ex_data * Note we get called twice, once for private key, and once for public * We need to get the EC_PARAMS and EC_POINT into both, * as lib11 dates from RSA only where all the pub key components * were also part of the private key. With EC the point * is not in the private key, and the params may or may not be. * */ static EVP_PKEY *pkcs11_get_evp_key_ec(PKCS11_KEY *key) { EVP_PKEY *pk; EC_KEY *ec; ec = pkcs11_get_ec(key); if (ec == NULL) return NULL; pk = EVP_PKEY_new(); if (pk == NULL) { EC_KEY_free(ec); return NULL; } EVP_PKEY_set1_EC_KEY(pk, ec); /* Also increments the ec ref count */ if (key->isPrivate) { #if OPENSSL_VERSION_NUMBER >= 0x10100000L EC_KEY_set_method(ec, PKCS11_get_ec_key_method()); #else ECDSA_set_method(ec, PKCS11_get_ecdsa_method()); ECDH_set_method(ec, PKCS11_get_ecdh_method()); #endif } /* TODO: Retrieve the ECDSA private key object attributes instead, * unless the key has the "sensitive" attribute set */ #if OPENSSL_VERSION_NUMBER >= 0x10100000L EC_KEY_set_ex_data(ec, ec_ex_index, key); #else ECDSA_set_ex_data(ec, ec_ex_index, key); #endif EC_KEY_free(ec); /* Drops our reference to it */ return pk; }
void makeecreq256(char* commonname) { EC_KEY *key; EVP_PKEY *pkey; X509_REQ *req; FILE *out; key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); EC_KEY_generate_key(key); EC_KEY_set_asn1_flag(key, OPENSSL_EC_NAMED_CURVE); pkey = EVP_PKEY_new(); EVP_PKEY_set1_EC_KEY(pkey, key); req = makereq(pkey, commonname, EVP_sha256()); out = fopen("ec256_req.pem", "w"); if (out == NULL) exit(-1); PEM_write_X509_REQ(out, req); fclose(out); out = fopen("ec256_req_key.pem", "w"); if (out == NULL) exit(-1); PEM_write_ECPrivateKey(out, key, NULL, NULL, 0, NULL, NULL); fclose(out); }
// Encode into PKCS#8 DER ByteString OSSLECPrivateKey::PKCS8Encode() { ByteString der; if (eckey == NULL) return der; EVP_PKEY* pkey = EVP_PKEY_new(); if (pkey == NULL) return der; if (!EVP_PKEY_set1_EC_KEY(pkey, eckey)) { EVP_PKEY_free(pkey); return der; } PKCS8_PRIV_KEY_INFO* p8inf = EVP_PKEY2PKCS8(pkey); EVP_PKEY_free(pkey); if (p8inf == NULL) return der; int len = i2d_PKCS8_PRIV_KEY_INFO(p8inf, NULL); if (len < 0) { PKCS8_PRIV_KEY_INFO_free(p8inf); return der; } der.resize(len); unsigned char* priv = &der[0]; int len2 = i2d_PKCS8_PRIV_KEY_INFO(p8inf, &priv); PKCS8_PRIV_KEY_INFO_free(p8inf); if (len2 != len) der.wipe(); return der; }
soter_status_t soter_ec_gen_key(EVP_PKEY_CTX *pkey_ctx) { EVP_PKEY *pkey; EC_KEY *ec=NULL; if (!pkey_ctx){ return SOTER_INVALID_PARAMETER; } pkey = EVP_PKEY_CTX_get0_pkey(pkey_ctx); if (!pkey){ return SOTER_INVALID_PARAMETER; } if (EVP_PKEY_EC != EVP_PKEY_id(pkey)){ return SOTER_INVALID_PARAMETER; } /* ec = EVP_PKEY_get0_EC_KEY(pkey); */ /* if (NULL == ec){ */ /* return SOTER_INVALID_PARAMETER; */ /* } */ ec = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); if(!ec){ return SOTER_ENGINE_FAIL; } if (!EC_KEY_generate_key(ec)){ return SOTER_ENGINE_FAIL; } if(!EVP_PKEY_set1_EC_KEY(pkey, ec)){ return SOTER_ENGINE_FAIL; } EC_KEY_free(ec); return SOTER_SUCCESS; }
static isc_result_t opensslecdsa_fromdns(dst_key_t *key, isc_buffer_t *data) { isc_result_t ret; EVP_PKEY *pkey; EC_KEY *eckey = NULL; isc_region_t r; int group_nid; unsigned int len; const unsigned char *cp; unsigned char buf[DNS_KEY_ECDSA384SIZE + 1]; REQUIRE(key->key_alg == DST_ALG_ECDSA256 || key->key_alg == DST_ALG_ECDSA384); if (key->key_alg == DST_ALG_ECDSA256) { len = DNS_KEY_ECDSA256SIZE; group_nid = NID_X9_62_prime256v1; } else { len = DNS_KEY_ECDSA384SIZE; group_nid = NID_secp384r1; } isc_buffer_remainingregion(data, &r); if (r.length == 0) return (ISC_R_SUCCESS); if (r.length < len) return (DST_R_INVALIDPUBLICKEY); eckey = EC_KEY_new_by_curve_name(group_nid); if (eckey == NULL) return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); buf[0] = POINT_CONVERSION_UNCOMPRESSED; memmove(buf + 1, r.base, len); cp = buf; if (o2i_ECPublicKey(&eckey, (const unsigned char **) &cp, (long) len + 1) == NULL) DST_RET (dst__openssl_toresult(DST_R_INVALIDPUBLICKEY)); if (EC_KEY_check_key(eckey) != 1) DST_RET (dst__openssl_toresult(DST_R_INVALIDPUBLICKEY)); pkey = EVP_PKEY_new(); if (pkey == NULL) DST_RET (ISC_R_NOMEMORY); if (!EVP_PKEY_set1_EC_KEY(pkey, eckey)) { EVP_PKEY_free(pkey); DST_RET (dst__openssl_toresult(ISC_R_FAILURE)); } isc_buffer_forward(data, len); key->keydata.pkey = pkey; key->key_size = len * 4; ret = ISC_R_SUCCESS; err: if (eckey != NULL) EC_KEY_free(eckey); return (ret); }
static isc_result_t opensslecdsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { dst_private_t priv; isc_result_t ret; EVP_PKEY *pkey; EC_KEY *eckey = NULL; BIGNUM *privkey; int group_nid; isc_mem_t *mctx = key->mctx; REQUIRE(key->key_alg == DST_ALG_ECDSA256 || key->key_alg == DST_ALG_ECDSA384); if (key->key_alg == DST_ALG_ECDSA256) group_nid = NID_X9_62_prime256v1; else group_nid = NID_secp384r1; eckey = EC_KEY_new_by_curve_name(group_nid); if (eckey == NULL) return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); /* read private key file */ ret = dst__privstruct_parse(key, DST_ALG_ECDSA256, lexer, mctx, &priv); if (ret != ISC_R_SUCCESS) goto err; privkey = BN_bin2bn(priv.elements[0].data, priv.elements[0].length, NULL); if (privkey == NULL) DST_RET(ISC_R_NOMEMORY); if (!EC_KEY_set_private_key(eckey, privkey)) DST_RET(ISC_R_NOMEMORY); if (ecdsa_check(eckey, pub) != ISC_R_SUCCESS) DST_RET(DST_R_INVALIDPRIVATEKEY); dst__privstruct_free(&priv, mctx); memset(&priv, 0, sizeof(priv)); pkey = EVP_PKEY_new(); if (pkey == NULL) DST_RET (ISC_R_NOMEMORY); if (!EVP_PKEY_set1_EC_KEY(pkey, eckey)) { EVP_PKEY_free(pkey); DST_RET (ISC_R_FAILURE); } key->keydata.pkey = pkey; ret = ISC_R_SUCCESS; err: if (eckey != NULL) EC_KEY_free(eckey); dst__privstruct_free(&priv, mctx); memset(&priv, 0, sizeof(priv)); return (ret); }
static int ecdh_cms_set_peerkey(EVP_PKEY_CTX *pctx, X509_ALGOR *alg, ASN1_BIT_STRING *pubkey) { ASN1_OBJECT *aoid; int atype; void *aval; int rv = 0; EVP_PKEY *pkpeer = NULL; EC_KEY *ecpeer = NULL; const unsigned char *p; int plen; X509_ALGOR_get0(&aoid, &atype, &aval, alg); if (OBJ_obj2nid(aoid) != NID_X9_62_id_ecPublicKey) goto err; /* If absent parameters get group from main key */ if (atype == V_ASN1_UNDEF || atype == V_ASN1_NULL) { const EC_GROUP *grp; EVP_PKEY *pk; pk = EVP_PKEY_CTX_get0_pkey(pctx); if (!pk) goto err; grp = EC_KEY_get0_group(pk->pkey.ec); ecpeer = EC_KEY_new(); if (!ecpeer) goto err; if (!EC_KEY_set_group(ecpeer, grp)) goto err; } else { ecpeer = eckey_type2param(atype, aval); if (!ecpeer) goto err; } /* We have parameters now set public key */ plen = ASN1_STRING_length(pubkey); p = ASN1_STRING_data(pubkey); if (!p || !plen) goto err; if (!o2i_ECPublicKey(&ecpeer, &p, plen)) goto err; pkpeer = EVP_PKEY_new(); if (!pkpeer) goto err; EVP_PKEY_set1_EC_KEY(pkpeer, ecpeer); if (EVP_PKEY_derive_set_peer(pctx, pkpeer) > 0) rv = 1; err: if (ecpeer) EC_KEY_free(ecpeer); if (pkpeer) EVP_PKEY_free(pkpeer); return rv; }
int EC_KEY_print(BIO *bp, const EC_KEY *x, int off) { EVP_PKEY *pk; int ret; pk = EVP_PKEY_new(); if (!pk || !EVP_PKEY_set1_EC_KEY(pk, (EC_KEY *)x)) return 0; ret = EVP_PKEY_print_private(bp, pk, off, NULL); EVP_PKEY_free(pk); return ret; }
int ECParameters_print(BIO *bp, const EC_KEY *x) { EVP_PKEY *pk; int ret; pk = EVP_PKEY_new(); if (!pk || !EVP_PKEY_set1_EC_KEY(pk, (EC_KEY *)x)) return 0; ret = EVP_PKEY_print_params(bp, pk, 4, NULL); EVP_PKEY_free(pk); return ret; }
int i2d_EC_PUBKEY(const EC_KEY *a, unsigned char **pp) { EVP_PKEY *pktmp; int ret; if (!a) return(0); if ((pktmp = EVP_PKEY_new()) == NULL) { OPENSSL_PUT_ERROR(X509, i2d_EC_PUBKEY, ERR_R_MALLOC_FAILURE); return(0); } EVP_PKEY_set1_EC_KEY(pktmp, (EC_KEY*) a); ret = i2d_PUBKEY(pktmp, pp); EVP_PKEY_free(pktmp); return(ret); }
int i2d_EC_PUBKEY(EC_KEY *a, unsigned char **pp) { EVP_PKEY *pktmp; int ret; if (!a) return(0); if ((pktmp = EVP_PKEY_new()) == NULL) { ASN1err(ASN1_F_I2D_EC_PUBKEY, ERR_R_MALLOC_FAILURE); return(0); } EVP_PKEY_set1_EC_KEY(pktmp, a); ret = i2d_PUBKEY(pktmp, pp); EVP_PKEY_free(pktmp); return(ret); }
int EVP_PKEY_set_std_dp(EVP_PKEY *key, int stnd_dp) { DH *dh = NULL; EC_KEY *ec = NULL; if (!key) { log_err("Invalid arguments"); return 0; } /* Generate key from standardized domain parameters */ switch(stnd_dp) { case 0: case 1: case 2: if (!init_dh(&dh, stnd_dp)) return 0; EVP_PKEY_set1_DH(key, dh); /* Decrement reference count */ DH_free(dh); break; case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15: case 16: case 17: case 18: if (!init_ecdh(&ec, stnd_dp)) return 0; EVP_PKEY_set1_EC_KEY(key, ec); /* Decrement reference count */ EC_KEY_free(ec); break; default: log_err("Invalid arguments"); return 0; } return 1; }
static isc_result_t opensslecdsa_generate(dst_key_t *key, int unused, void (*callback)(int)) { isc_result_t ret; EVP_PKEY *pkey; EC_KEY *eckey = NULL; int group_nid; REQUIRE(key->key_alg == DST_ALG_ECDSA256 || key->key_alg == DST_ALG_ECDSA384); UNUSED(unused); UNUSED(callback); if (key->key_alg == DST_ALG_ECDSA256) { group_nid = NID_X9_62_prime256v1; key->key_size = DNS_KEY_ECDSA256SIZE * 4; } else { group_nid = NID_secp384r1; key->key_size = DNS_KEY_ECDSA384SIZE * 4; } eckey = EC_KEY_new_by_curve_name(group_nid); if (eckey == NULL) return (dst__openssl_toresult2("EC_KEY_new_by_curve_name", DST_R_OPENSSLFAILURE)); if (EC_KEY_generate_key(eckey) != 1) DST_RET (dst__openssl_toresult2("EC_KEY_generate_key", DST_R_OPENSSLFAILURE)); pkey = EVP_PKEY_new(); if (pkey == NULL) DST_RET (ISC_R_NOMEMORY); if (!EVP_PKEY_set1_EC_KEY(pkey, eckey)) { EVP_PKEY_free(pkey); DST_RET (ISC_R_FAILURE); } key->keydata.pkey = pkey; ret = ISC_R_SUCCESS; err: if (eckey != NULL) EC_KEY_free(eckey); return (ret); }
soter_status_t soter_asym_ka_init(soter_asym_ka_t* asym_ka_ctx, soter_asym_ka_alg_t alg) { EVP_PKEY *pkey; int nid = soter_alg_to_curve_nid(alg); if ((!asym_ka_ctx) || (0 == nid)) { return SOTER_INVALID_PARAMETER; } pkey = EVP_PKEY_new(); if (!pkey) { return SOTER_NO_MEMORY; } if (!EVP_PKEY_set_type(pkey, EVP_PKEY_EC)) { EVP_PKEY_free(pkey); return SOTER_FAIL; } asym_ka_ctx->pkey_ctx = EVP_PKEY_CTX_new(pkey, NULL); if (!(asym_ka_ctx->pkey_ctx)) { EVP_PKEY_free(pkey); return SOTER_FAIL; } EC_KEY* ec = EC_KEY_new_by_curve_name(nid); if( !ec ){ EVP_PKEY_CTX_free(asym_ka_ctx->pkey_ctx); return SOTER_FAIL; } if(1!=EVP_PKEY_set1_EC_KEY(pkey, ec)){ EVP_PKEY_CTX_free(asym_ka_ctx->pkey_ctx); EC_KEY_free(ec); return SOTER_FAIL; } EC_KEY_free(ec); return SOTER_SUCCESS; }
static bool _cjose_jwk_evp_key_from_ec_key( cjose_jwk_t *jwk, EVP_PKEY **key, cjose_err *err) { // validate that the jwk is of type EC and we have a valid out-param if (NULL == jwk || CJOSE_JWK_KTY_EC != jwk->kty || NULL == jwk->keydata || NULL == key || NULL != *key) { CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG); goto _cjose_jwk_evp_key_from_ec_key_fail; } // create a blank EVP_PKEY *key = EVP_PKEY_new(); if (NULL == key) { CJOSE_ERROR(err, CJOSE_ERR_CRYPTO); goto _cjose_jwk_evp_key_from_ec_key_fail; } // assign the EVP_PKEY to reference the jwk's internal EC_KEY structure if (1 != EVP_PKEY_set1_EC_KEY( *key, ((struct _ec_keydata_int *)(jwk->keydata))->key)) { CJOSE_ERROR(err, CJOSE_ERR_CRYPTO); goto _cjose_jwk_evp_key_from_ec_key_fail; } // happy path return true; // fail path _cjose_jwk_evp_key_from_ec_key_fail: EVP_PKEY_free(*key); *key = NULL; return false; }
static void test_ecdsa_sign(void) { EVP_PKEY *pkey; { /* create pkey */ EC_KEY *eckey = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); EC_KEY_generate_key(eckey); pkey = EVP_PKEY_new(); EVP_PKEY_set1_EC_KEY(pkey, eckey); EC_KEY_free(eckey); } const char *message = "hello world"; ptls_buffer_t sigbuf; uint8_t sigbuf_small[1024]; ptls_buffer_init(&sigbuf, sigbuf_small, sizeof(sigbuf_small)); ok(do_sign(pkey, &sigbuf, ptls_iovec_init(message, strlen(message)), EVP_sha256()) == 0); EVP_PKEY_up_ref(pkey); ok(verify_sign(pkey, ptls_iovec_init(message, strlen(message)), ptls_iovec_init(sigbuf.base, sigbuf.off)) == 0); ptls_buffer_dispose(&sigbuf); EVP_PKEY_free(pkey); }
/* * Get EC key material and stash pointer in ex_data * Note we get called twice, once for private key, and once for public * We need to get the EC_PARAMS and EC_POINT into both, * as lib11 dates from RSA only where all the pub key components * were also part of the private key. With EC the point * is not in the private key, and the params may or may not be. * */ static EVP_PKEY *pkcs11_get_evp_key_ec(PKCS11_KEY * key) { EVP_PKEY *pk; EC_KEY * ec = NULL; CK_RV ckrv; size_t ec_paramslen = 0; CK_BYTE * ec_params = NULL; size_t ec_pointlen = 0; CK_BYTE * ec_point = NULL; PKCS11_KEY * pubkey; ASN1_OCTET_STRING *os=NULL; pk = EVP_PKEY_new(); if (pk == NULL) return NULL; ec = EC_KEY_new(); if (ec == NULL) { EVP_PKEY_free(pk); return NULL; } EVP_PKEY_set1_EC_KEY(pk, ec); /* Also increments the ec ref count */ /* For Openssl req we need at least the * EC_KEY_get0_group(ec_key)) to return the group. * Even if it fails will continue as a sign only does not need * need this if the pkcs11 or card can figure this out. */ if (key_getattr_var(key, CKA_EC_PARAMS, NULL, &ec_paramslen) == CKR_OK && ec_paramslen > 0) { ec_params = OPENSSL_malloc(ec_paramslen); if (ec_params) { ckrv = key_getattr_var(key, CKA_EC_PARAMS, ec_params, &ec_paramslen); if (ckrv == CKR_OK) { const unsigned char * a = ec_params; /* convert to OpenSSL parmas */ d2i_ECParameters(&ec, &a, (long) ec_paramslen); } } } /* Now get the ec_point */ pubkey = key->isPrivate ? PKCS11_find_key_from_key(key) : key; if (pubkey) { ckrv = key_getattr_var(pubkey, CKA_EC_POINT, NULL, &ec_pointlen); if (ckrv == CKR_OK && ec_pointlen > 0) { ec_point = OPENSSL_malloc(ec_pointlen); if (ec_point) { ckrv = key_getattr_var(pubkey, CKA_EC_POINT, ec_point, &ec_pointlen); if (ckrv == CKR_OK) { /* PKCS#11 returns ASN1 octstring*/ const unsigned char * a; /* we have asn1 octet string, need to strip off 04 len */ a = ec_point; os = d2i_ASN1_OCTET_STRING(NULL, &a, (long) ec_pointlen); if (os) { a = os->data; o2i_ECPublicKey(&ec, &a, os->length); } /* EC_KEY_print_fp(stderr, ec, 5); */ } } } } /* If the key is not extractable, create a key object * that will use the card's functions to sign & decrypt */ if (os) ASN1_STRING_free(os); if (ec_point) OPENSSL_free(ec_point); if (ec_params) OPENSSL_free(ec_params); if (key->isPrivate) { #if OPENSSL_VERSION_NUMBER >= 0x10100000L EC_KEY_set_method(ec, PKCS11_get_ec_key_method()); #else ECDSA_set_method(ec, PKCS11_get_ecdsa_method()); /* TODO: Retrieve the ECDSA private key object attributes instead, * unless the key has the "sensitive" attribute set */ #endif } /* TODO: Extract the ECDSA private key instead, if the key * is marked as extractable (and not private?) */ #if OPENSSL_VERSION_NUMBER >= 0x10100002L EC_KEY_set_ex_data(ec,ec_key_ex_index, key); #else ECDSA_set_ex_data(ec, ecdsa_ex_index, key); #endif EC_KEY_free(ec); /* drops our reference to it */ return pk; }
EVP_PKEY * EVP_PKEY_dup(EVP_PKEY *key) { EVP_PKEY *out = NULL; DH *dh_in = NULL, *dh_out = NULL; EC_KEY *ec_in = NULL, *ec_out = NULL; RSA *rsa_in = NULL, *rsa_out = NULL; check(key, "Invalid arguments"); out = EVP_PKEY_new(); if (!out) goto err; switch (EVP_PKEY_base_id(key)) { case EVP_PKEY_DH: dh_in = EVP_PKEY_get1_DH(key); if (!dh_in) goto err; dh_out = DHparams_dup_with_q(dh_in); if (!dh_out) goto err; EVP_PKEY_set1_DH(out, dh_out); DH_free(dh_out); DH_free(dh_in); break; case EVP_PKEY_EC: ec_in = EVP_PKEY_get1_EC_KEY(key); if (!ec_in) goto err; ec_out = EC_KEY_dup(ec_in); if (!ec_out) goto err; EVP_PKEY_set1_EC_KEY(out, ec_out); EC_KEY_free(ec_out); EC_KEY_free(ec_in); break; case EVP_PKEY_RSA: rsa_in = EVP_PKEY_get1_RSA(key); if (!rsa_in) goto err; rsa_out = RSAPrivateKey_dup(rsa_in); if (!rsa_out) goto err; EVP_PKEY_set1_RSA(out, rsa_out); RSA_free(rsa_out); RSA_free(rsa_in); break; default: log_err("Unknown protocol"); goto err; } return out; err: if (dh_in) DH_free(dh_in); if (ec_in) EC_KEY_free(ec_in); if (rsa_in) RSA_free(rsa_in); return NULL; }
int32_t CryptoNative_EvpPkeySetEcKey(EVP_PKEY* pkey, EC_KEY* key) { return EVP_PKEY_set1_EC_KEY(pkey, key); }
int ecdh_gm_compute_key(PACE_CTX * ctx, const BUF_MEM * s, const BUF_MEM * in, BN_CTX *bn_ctx) { int ret = 0; BUF_MEM * mem_h = NULL; BIGNUM * bn_s = NULL, *order = NULL, *cofactor = NULL; EC_POINT * ecp_h = NULL, *ecp_g = NULL; const ECDH_METHOD *default_method; EC_GROUP *group = NULL; EC_KEY *static_key = NULL, *ephemeral_key = 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); check(static_key, "could not get key object"); /* Extract group parameters */ group = EC_GROUP_dup(EC_KEY_get0_group(static_key)); order = BN_CTX_get(bn_ctx); cofactor = BN_CTX_get(bn_ctx); check(group && cofactor, "internal error"); if (!EC_GROUP_get_order(group, order, bn_ctx) || !EC_GROUP_get_cofactor(group, cofactor, bn_ctx)) goto err; /* Convert nonce to BIGNUM */ bn_s = BN_bin2bn((unsigned char *) s->data, s->length, bn_s); if (!bn_s) goto err; default_method = ECDH_get_default_method(); ECDH_set_default_method(ECDH_OpenSSL_Point()); /* complete the ECDH and get the resulting point h */ mem_h = ecdh_compute_key(ctx->static_key, in, bn_ctx); ECDH_set_default_method(default_method); ecp_h = EC_POINT_new(group); if (!mem_h || !ecp_h || !EC_POINT_oct2point(group, ecp_h, (unsigned char *) mem_h->data, mem_h->length, bn_ctx)) goto err; /* map to new generator */ ecp_g = EC_POINT_new(group); /* g' = g*s + h*1 */ if (!EC_POINT_mul(group, ecp_g, bn_s, ecp_h, BN_value_one(), bn_ctx)) 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 */ if (!EC_GROUP_set_generator(group, ecp_g, order, cofactor) || !EC_GROUP_check(group, bn_ctx) || !EC_KEY_set_group(ephemeral_key, group)) goto err; ret = 1; err: if (ecp_g) EC_POINT_clear_free(ecp_g); if (ecp_h) EC_POINT_clear_free(ecp_h); if (mem_h) BUF_MEM_free(mem_h); if (bn_s) BN_clear_free(bn_s); BN_CTX_end(bn_ctx); /* 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); if (group) EC_GROUP_clear_free(group); return ret; }
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; }
int EVP_PKEY_set_keys(EVP_PKEY *evp_pkey, const unsigned char *privkey, size_t privkey_len, const unsigned char *pubkey, size_t pubkey_len, BN_CTX *bn_ctx) { EC_KEY *ec_key = NULL; DH *dh = NULL; EC_POINT *ec_point = NULL; BIGNUM *bn = NULL, *dh_pub_key, *dh_priv_key; int ok = 0; const EC_GROUP *group; check(evp_pkey, "Invalid arguments"); switch (EVP_PKEY_base_id(evp_pkey)) { case EVP_PKEY_EC: ec_key = EVP_PKEY_get1_EC_KEY(evp_pkey); if (!ec_key) goto err; group = EC_KEY_get0_group(ec_key); if (pubkey) { ec_point = EC_POINT_new(group); if (!ec_point || !EC_POINT_oct2point(group, ec_point, pubkey, pubkey_len, bn_ctx) || !EC_KEY_set_public_key(ec_key, ec_point)) goto err; } if (privkey) { bn = BN_bin2bn(privkey, privkey_len, bn); if (!bn || !EC_KEY_set_private_key(ec_key, bn)) goto err; } if (!EVP_PKEY_set1_EC_KEY(evp_pkey, ec_key)) goto err; break; case EVP_PKEY_DH: dh = EVP_PKEY_get1_DH(evp_pkey); if (!dh) goto err; if (pubkey) { dh_pub_key = BN_bin2bn(pubkey, pubkey_len, NULL); if (!dh_pub_key || !DH_set0_key(dh, dh_pub_key, NULL)) goto err; } if (privkey) { dh_priv_key = BN_bin2bn(privkey, privkey_len, NULL); if (!dh_priv_key || !DH_set0_key(dh, NULL, dh_priv_key)) goto err; } if (!EVP_PKEY_set1_DH(evp_pkey, dh)) goto err; break; default: log_err("Unknown type of key"); goto err; break; } ok = 1; err: if (bn) BN_clear_free(bn); if (ec_key) EC_KEY_free(ec_key); if (dh) DH_free(dh); if (ec_point) EC_POINT_clear_free(ec_point); return ok; }
extern "C" int32_t EvpPkeySetEcKey(EVP_PKEY* pkey, EC_KEY* key) { return EVP_PKEY_set1_EC_KEY(pkey, key); }
int main(int argc, char **argv) { int r, i; KDF_FUNC kdf = NULL; EC_GROUP *ec_group = NULL; EC_KEY *ec_key = NULL; EVP_PKEY *pkey = NULL; EVP_PKEY *pub_key = NULL; EVP_PKEY *priv_key = NULL; X509_ALGOR *map = NULL; CPK_MASTER_SECRET *master = NULL; CPK_PUBLIC_PARAMS *params = NULL; BIO *bio_out = NULL; unsigned char *buf = NULL; unsigned char *p; const unsigned char *cp; int len; /* init openssl global functions */ ERR_load_crypto_strings(); OpenSSL_add_all_algorithms(); /* prepare cpk setup parameters */ ec_key = EC_KEY_new_by_curve_name(OBJ_sn2nid("prime192v1")); assert(ec_key != NULL); EC_GROUP_set_asn1_flag((EC_GROUP *)EC_KEY_get0_group(ec_key), OPENSSL_EC_NAMED_CURVE); r = EC_KEY_generate_key(ec_key); assert(r == 1); pkey = EVP_PKEY_new(); assert(pkey != NULL); r = EVP_PKEY_set1_EC_KEY(pkey, ec_key); assert(r == 1); map = CPK_MAP_new_default(); assert(map != NULL); //EVP_PKEY_print_fp(pkey, stdout); /* generate master_secret and public_params */ master = CPK_MASTER_SECRET_create("domainid", pkey, map); OPENSSL_assert(master); bio_out = BIO_new_fp(stdout, BIO_NOCLOSE); OPENSSL_assert(bio_out); r = CPK_MASTER_SECRET_print(bio_out, master, 0, 0); assert(r == 1); EVP_PKEY_free(pkey); pkey = NULL; pkey = CPK_MASTER_SECRET_extract_private_key(master, "id"); assert(pkey != NULL); EVP_PKEY_free(pkey); //pkey = CPK_MASTER_SECRET_extract_private_key(master, NULL); //assert(pkey == NULL); pkey = CPK_MASTER_SECRET_extract_private_key(master, id_long); assert(pkey != NULL); printf("EVP_PKEY of '%s':\n", id_long); EVP_PKEY_print_fp(pkey, stdout); printf("\n"); params = CPK_MASTER_SECRET_extract_public_params(master); assert(params); r = CPK_PUBLIC_PARAMS_print(bio_out, params, 0, 0); assert(r == 1); printf("\n"); printf("test CPK_PUBLIC_PARAMS_extract_public_key()\n"); pub_key = CPK_PUBLIC_PARAMS_extract_public_key(params, id_short); assert(pub_key != NULL); EVP_PKEY_free(pub_key); pub_key = CPK_PUBLIC_PARAMS_extract_public_key(params, id_long); assert(pub_key != NULL); printf("Public Key of '%s':\n", id_long); EVP_PKEY_print_fp(pkey, stdout); printf("\n"); r = CPK_MASTER_SECRET_validate_public_params(master, params); assert(r == 1); if (priv_key) EVP_PKEY_free(priv_key); priv_key = CPK_MASTER_SECRET_extract_private_key(master, "identity"); assert(priv_key); r = CPK_PUBLIC_PARAMS_validate_private_key(params, "identity", priv_key); assert(r == 1); r = CPK_PUBLIC_PARAMS_validate_private_key(params, "id", priv_key); assert(r == 0); /* der encoding and decoding */ len = i2d_CPK_MASTER_SECRET(master, NULL); assert(len > 0); if (buf != NULL) OPENSSL_free(buf); buf = OPENSSL_malloc(len); assert(buf != NULL); p = buf; len = i2d_CPK_MASTER_SECRET(master, &p); assert(len > 0); assert(p - buf == len); cp = buf; if (master) CPK_MASTER_SECRET_free(master); master = NULL; master = d2i_CPK_MASTER_SECRET(NULL, &cp, len); assert(master != NULL); r = CPK_MASTER_SECRET_validate_public_params(master, params); assert(r == 1); kdf = KDF_get_x9_63(EVP_sha1()); assert(kdf != NULL); if (priv_key != NULL) EVP_PKEY_free(priv_key); priv_key = CPK_MASTER_SECRET_extract_private_key(master, "Alice"); assert(priv_key != NULL); if (buf != NULL) OPENSSL_free(buf); buf = OPENSSL_malloc(1024); assert(buf != NULL); r = CPK_PUBLIC_PARAMS_compute_share_key(params, buf, 64, "Bob", priv_key, kdf); for (i = 0; i < 64; i++) printf("%02x", buf[i]); printf("\n"); if (priv_key != NULL) EVP_PKEY_free(priv_key); priv_key = CPK_MASTER_SECRET_extract_private_key(master, "Bob"); assert(priv_key != NULL); r = CPK_PUBLIC_PARAMS_compute_share_key(params, buf, 64, "Alice", priv_key, kdf); for (i = 0; i < 64; i++) printf("%02x", buf[i]); printf("\n"); printf("ok\n"); return 0; }
// Import a newly generated P256 pvt key and a certificate // to every slot and use the key to sign some data static void test_import_and_sign_all_10() { EVP_PKEY *evp; EC_KEY *eck; const EC_POINT *ecp; const BIGNUM *bn; char pvt[32]; X509 *cert; ASN1_TIME *tm; CK_BYTE i, j; CK_BYTE some_data[32]; CK_ULONG class_k = CKO_PRIVATE_KEY; CK_ULONG class_c = CKO_CERTIFICATE; CK_ULONG kt = CKK_ECDSA; CK_BYTE id = 0; CK_BYTE params[] = {0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07}; CK_BYTE sig[64]; CK_ULONG recv_len; CK_BYTE value_c[3100]; CK_ULONG cert_len; CK_BYTE der_encoded[80]; CK_BYTE_PTR der_ptr; CK_BYTE_PTR r_ptr; CK_BYTE_PTR s_ptr; CK_ULONG r_len; CK_ULONG s_len; unsigned char *p; CK_ATTRIBUTE privateKeyTemplate[] = { {CKA_CLASS, &class_k, sizeof(class_k)}, {CKA_KEY_TYPE, &kt, sizeof(kt)}, {CKA_ID, &id, sizeof(id)}, {CKA_EC_PARAMS, ¶ms, sizeof(params)}, {CKA_VALUE, pvt, sizeof(pvt)} }; CK_ATTRIBUTE publicKeyTemplate[] = { {CKA_CLASS, &class_c, sizeof(class_c)}, {CKA_ID, &id, sizeof(id)}, {CKA_VALUE, value_c, sizeof(value_c)} }; CK_OBJECT_HANDLE obj[24]; CK_SESSION_HANDLE session; CK_MECHANISM mech = {CKM_ECDSA, NULL}; evp = EVP_PKEY_new(); if (evp == NULL) exit(EXIT_FAILURE); eck = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); if (eck == NULL) exit(EXIT_FAILURE); asrt(EC_KEY_generate_key(eck), 1, "GENERATE ECK"); bn = EC_KEY_get0_private_key(eck); asrt(BN_bn2bin(bn, pvt), 32, "EXTRACT PVT"); if (EVP_PKEY_set1_EC_KEY(evp, eck) == 0) exit(EXIT_FAILURE); cert = X509_new(); if (cert == NULL) exit(EXIT_FAILURE); if (X509_set_pubkey(cert, evp) == 0) exit(EXIT_FAILURE); tm = ASN1_TIME_new(); if (tm == NULL) exit(EXIT_FAILURE); ASN1_TIME_set_string(tm, "000001010000Z"); X509_set_notBefore(cert, tm); X509_set_notAfter(cert, tm); cert->sig_alg->algorithm = OBJ_nid2obj(8); cert->cert_info->signature->algorithm = OBJ_nid2obj(8); ASN1_BIT_STRING_set_bit(cert->signature, 8, 1); ASN1_BIT_STRING_set(cert->signature, "\x00", 1); p = value_c; if ((cert_len = (CK_ULONG) i2d_X509(cert, &p)) == 0 || cert_len > sizeof(value_c)) exit(EXIT_FAILURE); publicKeyTemplate[2].ulValueLen = cert_len; asrt(funcs->C_Initialize(NULL), CKR_OK, "INITIALIZE"); asrt(funcs->C_OpenSession(0, CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL, NULL, &session), CKR_OK, "OpenSession1"); asrt(funcs->C_Login(session, CKU_SO, "010203040506070801020304050607080102030405060708", 48), CKR_OK, "Login SO"); for (i = 0; i < 24; i++) { id = i; asrt(funcs->C_CreateObject(session, publicKeyTemplate, 3, obj + i), CKR_OK, "IMPORT CERT"); asrt(funcs->C_CreateObject(session, privateKeyTemplate, 5, obj + i), CKR_OK, "IMPORT KEY"); } asrt(funcs->C_Logout(session), CKR_OK, "Logout SO"); for (i = 0; i < 24; i++) { for (j = 0; j < 10; j++) { if(RAND_pseudo_bytes(some_data, sizeof(some_data)) == -1) exit(EXIT_FAILURE); asrt(funcs->C_Login(session, CKU_USER, "123456", 6), CKR_OK, "Login USER"); asrt(funcs->C_SignInit(session, &mech, obj[i]), CKR_OK, "SignInit"); recv_len = sizeof(sig); asrt(funcs->C_Sign(session, some_data, sizeof(some_data), sig, &recv_len), CKR_OK, "Sign"); r_len = 32; s_len = 32; der_ptr = der_encoded; *der_ptr++ = 0x30; *der_ptr++ = 0xff; // placeholder, fix below r_ptr = sig; *der_ptr++ = 0x02; *der_ptr++ = r_len; if (*r_ptr >= 0x80) { *(der_ptr - 1) = *(der_ptr - 1) + 1; *der_ptr++ = 0x00; } else if (*r_ptr == 0x00 && *(r_ptr + 1) < 0x80) { r_len--; *(der_ptr - 1) = *(der_ptr - 1) - 1; r_ptr++; } memcpy(der_ptr, r_ptr, r_len); der_ptr+= r_len; s_ptr = sig + 32; *der_ptr++ = 0x02; *der_ptr++ = s_len; if (*s_ptr >= 0x80) { *(der_ptr - 1) = *(der_ptr - 1) + 1; *der_ptr++ = 0x00; } else if (*s_ptr == 0x00 && *(s_ptr + 1) < 0x80) { s_len--; *(der_ptr - 1) = *(der_ptr - 1) - 1; s_ptr++; } memcpy(der_ptr, s_ptr, s_len); der_ptr+= s_len; der_encoded[1] = der_ptr - der_encoded - 2; dump_hex(der_encoded, der_encoded[1] + 2, stderr, 1); asrt(ECDSA_verify(0, some_data, sizeof(some_data), der_encoded, der_encoded[1] + 2, eck), 1, "ECDSA VERIFICATION"); } } asrt(funcs->C_Logout(session), CKR_OK, "Logout USER"); asrt(funcs->C_CloseSession(session), CKR_OK, "CloseSession"); asrt(funcs->C_Finalize(NULL), CKR_OK, "FINALIZE"); }