EC_KEY_METHOD *PKCS11_get_ec_key_method(void) { int (*orig_sign)(int type, const unsigned char *dgst, int dlen, unsigned char *sig, unsigned int *siglen, const BIGNUM *kinv, const BIGNUM *r, EC_KEY *eckey) = NULL; int (*orig_sign_setup)(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp) = NULL; ECDSA_SIG *(*orig_sign_sig)(const unsigned char *dgst, int dgst_len, const BIGNUM *in_kinv, const BIGNUM *in_r, EC_KEY *eckey) = NULL; alloc_ec_key_ex_index(); if (ops == NULL) { ops = EC_KEY_METHOD_new((EC_KEY_METHOD *)EC_KEY_OpenSSL()); EC_KEY_METHOD_get_sign(ops, &orig_sign, &orig_sign_setup, &orig_sign_sig); EC_KEY_METHOD_set_sign(ops, orig_sign, pkcs11_ecdsa_sign_setup, pkcs11_ecdsa_do_sign); EC_KEY_METHOD_set_compute_key(ops, pkcs11_ec_ckey); } return ops; }
/** * ECDSA signing method (replaces ossl_ecdsa_sign_sig) * * @param dgst hash value to sign * @param dlen length of the hash value * @param kinv precomputed inverse k (from the sign_setup method) * @param rp precomputed rp (from the sign_setup method) * @param ec private EC signing key * @return pointer to a ECDSA_SIG structure or NULL if an error occurred */ static ECDSA_SIG *pkcs11_ecdsa_sign_sig(const unsigned char *dgst, int dlen, const BIGNUM *kinv, const BIGNUM *rp, EC_KEY *ec) { unsigned char sigret[512]; /* HACK for now */ ECDSA_SIG *sig; PKCS11_KEY *key; unsigned int siglen; BIGNUM *r, *s, *order; (void)kinv; /* Precomputed values are not used for PKCS#11 */ (void)rp; /* Precomputed values are not used for PKCS#11 */ key = pkcs11_get_ex_data_ec(ec); if (check_key_fork(key) < 0) { sign_sig_fn orig_sign_sig; #if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER) const EC_KEY_METHOD *meth = EC_KEY_OpenSSL(); EC_KEY_METHOD_get_sign((EC_KEY_METHOD *)meth, NULL, NULL, &orig_sign_sig); #else const ECDSA_METHOD *meth = ECDSA_OpenSSL(); orig_sign_sig = meth->ecdsa_do_sign; #endif return orig_sign_sig(dgst, dlen, kinv, rp, ec); } /* Truncate digest if its byte size is longer than needed */ order = BN_new(); if (order) { const EC_GROUP *group = EC_KEY_get0_group(ec); if (group && EC_GROUP_get_order(group, order, NULL)) { int klen = BN_num_bits(order); if (klen < 8*dlen) dlen = (klen+7)/8; } BN_free(order); } siglen = sizeof sigret; if (pkcs11_ecdsa_sign(dgst, dlen, sigret, &siglen, key) <= 0) return NULL; r = BN_bin2bn(sigret, siglen/2, NULL); s = BN_bin2bn(sigret + siglen/2, siglen/2, NULL); sig = ECDSA_SIG_new(); if (sig == NULL) return NULL; #if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER) ECDSA_SIG_set0(sig, r, s); #else BN_free(sig->r); sig->r = r; BN_free(sig->s); sig->s = s; #endif return sig; }
EC_KEY_METHOD *PKCS11_get_ec_key_method(void) { static EC_KEY_METHOD *ops = NULL; int (*orig_sign)(int, const unsigned char *, int, unsigned char *, unsigned int *, const BIGNUM *, const BIGNUM *, EC_KEY *) = NULL; alloc_ec_ex_index(); if (ops == NULL) { ops = EC_KEY_METHOD_new((EC_KEY_METHOD *)EC_KEY_OpenSSL()); EC_KEY_METHOD_get_sign(ops, &orig_sign, NULL, NULL); EC_KEY_METHOD_set_sign(ops, orig_sign, NULL, pkcs11_ecdsa_sign_sig); EC_KEY_METHOD_get_compute_key(ops, &ossl_ecdh_compute_key); EC_KEY_METHOD_set_compute_key(ops, pkcs11_ec_ckey); } return ops; }
/* * This internal function is used by ENGINE_openssl() and possibly by the * "dynamic" ENGINE support too */ static int bind_helper(ENGINE *e) { if (!ENGINE_set_id(e, engine_openssl_id) || !ENGINE_set_name(e, engine_openssl_name) || !ENGINE_set_destroy_function(e, openssl_destroy) #ifndef TEST_ENG_OPENSSL_NO_ALGORITHMS # ifndef OPENSSL_NO_RSA || !ENGINE_set_RSA(e, RSA_get_default_method()) # endif # ifndef OPENSSL_NO_DSA || !ENGINE_set_DSA(e, DSA_get_default_method()) # endif # ifndef OPENSSL_NO_EC || !ENGINE_set_EC(e, EC_KEY_OpenSSL()) # endif # ifndef OPENSSL_NO_DH || !ENGINE_set_DH(e, DH_get_default_method()) # endif || !ENGINE_set_RAND(e, RAND_OpenSSL()) # ifdef TEST_ENG_OPENSSL_RC4 || !ENGINE_set_ciphers(e, openssl_ciphers) # endif # ifdef TEST_ENG_OPENSSL_SHA || !ENGINE_set_digests(e, openssl_digests) # endif #endif #ifdef TEST_ENG_OPENSSL_PKEY || !ENGINE_set_load_privkey_function(e, openssl_load_privkey) #endif #ifdef TEST_ENG_OPENSSL_HMAC || !ossl_register_hmac_meth() || !ENGINE_set_pkey_meths(e, ossl_pkey_meths) #endif ) return 0; /* * If we add errors to this ENGINE, ensure the error handling is setup * here */ /* openssl_load_error_strings(); */ return 1; }
void EC_KEY_set_default_secg_method(void) { default_ec_key_meth = EC_KEY_OpenSSL(); }