diff --git a/doc/tools/pkcs15-init.xml b/doc/tools/pkcs15-init.xml
index f0c27b6..793a490 100644
--- a/doc/tools/pkcs15-init.xml
+++ b/doc/tools/pkcs15-init.xml
@@ -134,10 +134,8 @@
 				key as a PKCS #15 public key object.
 			</para>
 			<para>
-				By default, <command>pkcs15-init</command> will try to use the card's
-				on-board key generation facilities, if available. If the card does not
-				support on-board key generation, <command>pkcs15-init</command> will fall
-				back to software key generation.
+				<command>pkcs15-init</command> will try to use the card's
+				on-board key generation facilities, if available.
 			</para>
 		</refsect2>
 
diff --git a/etc/opensc.conf.in b/etc/opensc.conf.in
index 0364cb0..212bd1c 100644
--- a/etc/opensc.conf.in
+++ b/etc/opensc.conf.in
@@ -364,12 +364,6 @@ app opensc-pkcs11 {
  		#
 		# Default: true
 		# lock_login = false;
-		#
-		# Set this value to true if you want to allow off-card
-		# keypair generation (in software on your pc)
-		#
-		# Default: false
-		# soft_keygen_allowed = true;
 
 		# User PIN unblock style
 		#    none:  PIN unblock is not possible with PKCS#11 API;
diff --git a/src/pkcs11/Makefile.am b/src/pkcs11/Makefile.am
index 5315170..b8212b4 100644
--- a/src/pkcs11/Makefile.am
+++ b/src/pkcs11/Makefile.am
@@ -12,7 +12,7 @@ INCLUDES = -I$(top_srcdir)/src
 
 OPENSC_PKCS11_INC = sc-pkcs11.h pkcs11.h pkcs11-opensc.h
 OPENSC_PKCS11_SRC = pkcs11-global.c pkcs11-session.c pkcs11-object.c misc.c slot.c \
-	mechanism.c openssl.c secretkey.c framework-pkcs15.c \
+	mechanism.c openssl.c framework-pkcs15.c \
 	framework-pkcs15init.c debug.c opensc-pkcs11.exports \
 	pkcs11-display.c pkcs11-display.h
 OPENSC_PKCS11_LIBS = $(OPTIONAL_OPENSSL_LIBS) $(PTHREAD_LIBS) \
diff --git a/src/pkcs11/Makefile.mak b/src/pkcs11/Makefile.mak
index 880c4b5..f7281db 100644
--- a/src/pkcs11/Makefile.mak
+++ b/src/pkcs11/Makefile.mak
@@ -10,7 +10,7 @@ TARGET2			= libpkcs11.lib
 TARGET3			= pkcs11-spy.dll
 
 OBJECTS			= pkcs11-global.obj pkcs11-session.obj pkcs11-object.obj misc.obj slot.obj \
-			  mechanism.obj openssl.obj secretkey.obj framework-pkcs15.obj \
+			  mechanism.obj openssl.obj framework-pkcs15.obj \
 			  framework-pkcs15init.obj debug.obj \
 			  versioninfo.res
 OBJECTS2		= libpkcs11.obj versioninfo.res
diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c
index dccc575..7d3371e 100644
--- a/src/pkcs11/framework-pkcs15.c
+++ b/src/pkcs11/framework-pkcs15.c
@@ -1835,41 +1835,6 @@ static CK_RV pkcs15_gen_keypair(struct sc_pkcs11_card *p11card,
 		rv = sc_to_cryptoki_error(rc);
 		goto kpgen_done;
 	}
-	else {
-		/* 3.b Try key pair generation in software, if allowed */
-		
-		if (!sc_pkcs11_conf.soft_keygen_allowed) {
-			sc_debug(context, SC_LOG_DEBUG_NORMAL, "On card keypair gen not supported, software keypair gen not allowed");
-			rv = CKR_FUNCTION_FAILED;
-			goto kpgen_done;
-		}
-
-		sc_debug(context, SC_LOG_DEBUG_NORMAL, "Doing key pair generation in software\n");
-		rv = sc_pkcs11_gen_keypair_soft(keytype, keybits,
-			&keygen_args.prkey_args.key, &pub_args.key);
-		if (rv != CKR_OK) {
-			sc_debug(context, SC_LOG_DEBUG_NORMAL, "sc_pkcs11_gen_keypair_soft failed: 0x%0x\n", rv);
-			goto kpgen_done;
-		}
-
-		rc = sc_pkcs15init_store_private_key(p15card, profile, &keygen_args.prkey_args, &priv_key_obj);
-
-		if (rc >= 0) {
-			/* copy ID from private key(s) here to avoid bad link between private and public key */
-			memcpy(&pub_args.id.value, &keygen_args.prkey_args.id.value, keygen_args.prkey_args.id.len);
-			pub_args.id.len = keygen_args.prkey_args.id.len;
-			rc = sc_pkcs15init_store_public_key(p15card, profile, &pub_args, &pub_key_obj);
-		}
-
-		sc_pkcs15_erase_prkey(&keygen_args.prkey_args.key);
-		sc_pkcs15_erase_pubkey(&pub_args.key);
-
-		if (rc < 0) {
-			sc_debug(context, SC_LOG_DEBUG_NORMAL, "private/public keys not stored: %d\n", rc);
-			rv = sc_to_cryptoki_error(rc);
-			goto kpgen_done;
-		}
-	}
 
 	/* 4. Create new pkcs11 public and private key object */
 
@@ -2408,13 +2373,13 @@ pkcs15_prkey_decrypt(struct sc_pkcs11_session *ses, void *obj,
 	u8	decrypted[256];
 	int	buff_too_small, rv, flags = 0;
 
-	sc_debug(context, SC_LOG_DEBUG_NORMAL, "Initiating unwrap/decryption.\n");
+	sc_debug(context, SC_LOG_DEBUG_NORMAL, "Initiating decryption.\n");
 
-	/* See which of the alternative keys supports unwrap/decrypt */
+	/* See which of the alternative keys supports decryption */
 	prkey = (struct pkcs15_prkey_object *) obj;
 	while (prkey
 	 && !(prkey->prv_info->usage
-	     & (SC_PKCS15_PRKEY_USAGE_DECRYPT|SC_PKCS15_PRKEY_USAGE_UNWRAP)))
+	     & (SC_PKCS15_PRKEY_USAGE_DECRYPT)))
 		prkey = prkey->prv_next;
 
 	if (prkey == NULL)
@@ -2450,7 +2415,7 @@ pkcs15_prkey_decrypt(struct sc_pkcs11_session *ses, void *obj,
 
 	sc_unlock(ses->slot->card->card);
 
-	sc_debug(context, SC_LOG_DEBUG_NORMAL, "Key unwrap/decryption complete. Result %d.\n", rv);
+	sc_debug(context, SC_LOG_DEBUG_NORMAL, "Decryption complete. Result %d.\n", rv);
 
 	if (rv < 0)
 		return sc_to_cryptoki_error(rv);
@@ -2466,28 +2431,6 @@ pkcs15_prkey_decrypt(struct sc_pkcs11_session *ses, void *obj,
 	return CKR_OK;
 }
 
-static CK_RV
-pkcs15_prkey_unwrap(struct sc_pkcs11_session *ses, void *obj,
-		CK_MECHANISM_PTR pMechanism,
-		CK_BYTE_PTR pData, CK_ULONG ulDataLen,
-		CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount,
-		void **result)
-{
-	u8 unwrapped_key[256];
-	CK_ULONG key_len = sizeof(unwrapped_key);
-	int   r;
-
-	r = pkcs15_prkey_decrypt(ses, obj, pMechanism, pData, ulDataLen,
-			unwrapped_key, &key_len);
-
-	if (r < 0)
-		return sc_to_cryptoki_error(r);
-	return sc_pkcs11_create_secret_key(ses,
-			unwrapped_key, key_len,
-			pTemplate, ulAttributeCount,
-			(struct sc_pkcs11_object **) result);
-}
-
 struct sc_pkcs11_object_ops pkcs15_prkey_ops = {
 	pkcs15_prkey_release,
 	pkcs15_prkey_set_attribute,
@@ -2496,7 +2439,7 @@ struct sc_pkcs11_object_ops pkcs15_prkey_ops = {
 	NULL,
 	NULL,
 	pkcs15_prkey_sign,
-	pkcs15_prkey_unwrap,
+	NULL, /* pkcs15_prkey_unwrap */
 	pkcs15_prkey_decrypt
 };
 
diff --git a/src/pkcs11/openssl.c b/src/pkcs11/openssl.c
index e4beac6..973af6d 100644
--- a/src/pkcs11/openssl.c
+++ b/src/pkcs11/openssl.c
@@ -264,73 +264,6 @@ static void sc_pkcs11_openssl_md_release(sc_pkcs11_operation_t *op)
 	op->priv_data = NULL;
 }
 
-static int
-do_convert_bignum(sc_pkcs15_bignum_t *dst, BIGNUM *src)
-{
-	if (src == 0)
-		return 0;
-	dst->len = BN_num_bytes(src);
-	dst->data = (u8 *) malloc(dst->len);
-	if (dst->data == NULL)
-		return 0;
-	BN_bn2bin(src, dst->data);
-	return 1;
-}
-
-CK_RV
-sc_pkcs11_gen_keypair_soft(CK_KEY_TYPE keytype, CK_ULONG keybits,
-	struct sc_pkcs15_prkey *privkey, struct sc_pkcs15_pubkey *pubkey)
-{
-	switch (keytype) {
-	case CKK_RSA: {
-		RSA	*rsa;
-		BIO	*err;
-		struct sc_pkcs15_prkey_rsa  *sc_priv = &privkey->u.rsa;
-		struct sc_pkcs15_pubkey_rsa *sc_pub  = &pubkey->u.rsa;
-
-		err = BIO_new(BIO_s_mem());
-		rsa = RSA_generate_key(keybits, 0x10001, NULL, err);
-		BIO_free(err);
-		if (rsa == NULL) {
-			sc_debug(context, SC_LOG_DEBUG_NORMAL, "RSA_generate_key() failed\n");
-			return CKR_FUNCTION_FAILED;
-		}
-
-		privkey->algorithm = pubkey->algorithm = SC_ALGORITHM_RSA;
-
-		if (!do_convert_bignum(&sc_priv->modulus, rsa->n)
-		 || !do_convert_bignum(&sc_priv->exponent, rsa->e)
-		 || !do_convert_bignum(&sc_priv->d, rsa->d)
-		 || !do_convert_bignum(&sc_priv->p, rsa->p)
-		 || !do_convert_bignum(&sc_priv->q, rsa->q)) {
-		 	sc_debug(context, SC_LOG_DEBUG_NORMAL, "do_convert_bignum() failed\n");
-		 	RSA_free(rsa);
-			return CKR_FUNCTION_FAILED;
-		}
-		if (rsa->iqmp && rsa->dmp1 && rsa->dmq1) {
-			do_convert_bignum(&sc_priv->iqmp, rsa->iqmp);
-			do_convert_bignum(&sc_priv->dmp1, rsa->dmp1);
-			do_convert_bignum(&sc_priv->dmq1, rsa->dmq1);
-		}
-
-		if (!do_convert_bignum(&sc_pub->modulus, rsa->n)
-		 || !do_convert_bignum(&sc_pub->exponent, rsa->e)) {
-		 	sc_debug(context, SC_LOG_DEBUG_NORMAL, "do_convert_bignum() failed\n");
-		 	RSA_free(rsa);
-			return CKR_FUNCTION_FAILED;
-		}
-
-		RSA_free(rsa);
-
-		break;
-		}
-	default:
-		return CKR_MECHANISM_PARAM_INVALID;
-	}
-
-	return CKR_OK;
-}
-
 #if OPENSSL_VERSION_NUMBER >= 0x10000000L && !defined(OPENSSL_NO_EC)
 
 static void reverse(unsigned char *buf, size_t len)
diff --git a/src/pkcs11/pkcs11-object.c b/src/pkcs11/pkcs11-object.c
index 5c48298..a9532ba 100644
--- a/src/pkcs11/pkcs11-object.c
+++ b/src/pkcs11/pkcs11-object.c
@@ -965,51 +965,8 @@ CK_RV C_UnwrapKey(CK_SESSION_HANDLE hSession,	/* the session's handle */
 		  CK_ULONG ulAttributeCount,	/* # of attributes in template */
 		  CK_OBJECT_HANDLE_PTR phKey)
 {				/* gets handle of recovered key */
-	struct sc_pkcs11_session *session;
-	struct sc_pkcs11_object *object, *result;
-	int rv;
-
-	rv = sc_pkcs11_lock();
-	if (rv != CKR_OK)
-		return rv;
-
-	if (pMechanism == NULL_PTR || (pTemplate == NULL_PTR && ulAttributeCount > 0)) {
-		rv = CKR_ARGUMENTS_BAD;
-		goto out;
-	}
-
-	rv = get_object_from_session(hSession, hUnwrappingKey, &session, &object);
-	if (rv != CKR_OK) {
-		if (rv == CKR_OBJECT_HANDLE_INVALID)
-			rv = CKR_UNWRAPPING_KEY_HANDLE_INVALID;
-		goto out;
-	}
-
-	if (!(session->flags & CKF_RW_SESSION)) {
-		rv = CKR_SESSION_READ_ONLY;
-		goto out;
-	}
-
-	if (object->ops->sign == NULL_PTR) {
-		rv = CKR_KEY_TYPE_INCONSISTENT;
-		goto out;
-	}
-
-	rv = object->ops->unwrap_key(session, object, pMechanism,
-				     pWrappedKey, ulWrappedKeyLen,
-				     pTemplate, ulAttributeCount, (void **)&result);
-
-	sc_debug(context, SC_LOG_DEBUG_NORMAL, "C_UnwrapKey() = %s", lookup_enum ( RV_T, rv ));
-
-	if (rv == CKR_OK) {
-		result->handle = (long)result;
-		list_append(&session->slot->objects, result);
-
-	}
-	*phKey = result->handle;
-
-out:	sc_pkcs11_unlock();
-	return rv;
+	/* Unwrapping inside the card is not supported */
+	return CKR_FUNCTION_NOT_SUPPORTED;
 }
 
 CK_RV C_DeriveKey(CK_SESSION_HANDLE hSession,	/* the session's handle */
diff --git a/src/pkcs11/secretkey.c b/src/pkcs11/secretkey.c
deleted file mode 100644
index 82ab19c..0000000
--- a/src/pkcs11/secretkey.c
+++ /dev/null
@@ -1,233 +0,0 @@
-/*
- * Secret key handling for PKCS#11
- *
- * This module deals only with secret keys that have been unwrapped
- * by the card. At the moment, we do not support key unwrapping
- * where the key remains on the token.
- *
- * Copyright (C) 2002  Olaf Kirch <okir@lst.de>
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include "config.h"
-
-#include <stdlib.h>
-#include <string.h>
-
-#include "sc-pkcs11.h"
-
-struct pkcs11_secret_key {
-	struct sc_pkcs11_object object;
-
-	char *		label;
-	CK_KEY_TYPE	type;
-	CK_BYTE_PTR	value;
-	CK_ULONG	value_len;
-};
-
-extern struct sc_pkcs11_object_ops pkcs11_secret_key_ops;
-
-#define set_attr(var, attr)			\
-	if (attr->ulValueLen != sizeof(var))	\
-		return CKR_ATTRIBUTE_VALUE_INVALID; \
-	memcpy(&var, attr->pValue, attr->ulValueLen);
-#define check_attr(attr, size)			\
-	if (attr->pValue == NULL_PTR) {		\
-		attr->ulValueLen = size;	\
-		return CKR_OK;			\
-	}					\
-	if (attr->ulValueLen < size) {		\
-		attr->ulValueLen = size;	\
-		return CKR_BUFFER_TOO_SMALL;	\
-	}					\
-	attr->ulValueLen = size;
-#define get_attr(attr, type, value)		\
-	check_attr(attr, sizeof(type));		\
-	*(type *) (attr->pValue) = value;
-
-CK_RV
-sc_pkcs11_create_secret_key(struct sc_pkcs11_session *session,
-		const u8 *value, size_t value_len,
-		CK_ATTRIBUTE_PTR _template,
-		CK_ULONG attribute_count,
-		struct sc_pkcs11_object **out)
-{
-	struct pkcs11_secret_key *key;
-	CK_ATTRIBUTE_PTR attr;
-	int		n, rv;
-
-	key = (struct pkcs11_secret_key *) calloc(1, sizeof(*key));
-	if (!key)
-		return CKR_HOST_MEMORY;
-	key->value = (CK_BYTE *) malloc(value_len);
-	if (!key->value) {
-		pkcs11_secret_key_ops.release(key);
-		return CKR_HOST_MEMORY; /* XXX correct? */
-	}
-	memcpy(key->value, value, value_len);
-	key->value_len = value_len;
-	key->object.ops = &pkcs11_secret_key_ops;
-
-	/* Make sure the key type is given in the template */
-	for (n = attribute_count, attr = _template; n--; attr++) {
-		if (attr->type == CKA_KEY_TYPE) {
-			set_attr(key->type, attr);
-			break;
-		}
-	}
-	if (n < 0) {
-		pkcs11_secret_key_ops.release(key);
-		return CKR_TEMPLATE_INCOMPLETE;
-	}
-
-	/* Set all the other attributes */
-	for (n = attribute_count, attr = _template; n--; attr++) {
-		rv = key->object.ops->set_attribute(session, key, attr);
-		if (rv != CKR_OK) {
-			pkcs11_secret_key_ops.release(key);
-			return rv;
-		}
-	}
-
-	*out = (struct sc_pkcs11_object *) key;
-	return CKR_OK;
-}
-
-static void
-sc_pkcs11_secret_key_release(void *object)
-{
-	struct pkcs11_secret_key *key;
-
-	key = (struct pkcs11_secret_key *) object;
-	if (key) {
-		if (key->value)
-			free(key->value);
-		if (key->label)
-			free(key->label);
-		free(key);
-	}
-}
-
-static CK_RV
-sc_pkcs11_secret_key_set_attribute(struct sc_pkcs11_session *session,
-				void *object, CK_ATTRIBUTE_PTR attr)
-{
-	struct pkcs11_secret_key *key;
-	CK_OBJECT_CLASS	ck_class;
-	CK_KEY_TYPE ck_key_type;
-	CK_BBOOL ck_bbool;
-
-	key = (struct pkcs11_secret_key *) object;
-	switch (attr->type) {
-	case CKA_CLASS:
-		set_attr(ck_class, attr);
-		if (ck_class != CKO_SECRET_KEY)
-			return CKR_ATTRIBUTE_VALUE_INVALID;
-		break;
-	case CKA_KEY_TYPE:
-		set_attr(ck_key_type, attr);
-		if (ck_key_type != key->type)
-			return CKR_ATTRIBUTE_VALUE_INVALID;
-		break;
-	case CKA_LABEL:
-		if (key->label)
-			free(key->label);
-		key->label = strdup((const char *) attr->pValue);
-		break;
-	case CKA_TOKEN:
-		set_attr(ck_bbool, attr);
-		if (!ck_bbool)
-			return CKR_ATTRIBUTE_VALUE_INVALID;
-		break;
-	case CKA_VALUE:
-		if (key->value)
-			free(key->value);
-		key->value = (CK_BYTE *) malloc(attr->ulValueLen);
-		if (key->value == NULL)
-			return CKR_HOST_MEMORY;
-		key->value_len = attr->ulValueLen;
-		memcpy(key->value, attr->pValue, key->value_len);
-		break;
-	case CKA_ENCRYPT:
-	case CKA_DECRYPT:
-	case CKA_SIGN:
-	case CKA_VERIFY:
-	case CKA_WRAP:
-	case CKA_UNWRAP:
-	case CKA_EXTRACTABLE:
-	case CKA_ALWAYS_SENSITIVE:
-	case CKA_NEVER_EXTRACTABLE:
-		/* We ignore these for now, just making sure the argument
-		 * has the right size */
-		set_attr(ck_bbool, attr);
-		break;
-	default:
-		return CKR_ATTRIBUTE_TYPE_INVALID;
-	}
-
-	return CKR_OK;
-}
-
-static CK_RV
-sc_pkcs11_secret_key_get_attribute(struct sc_pkcs11_session *session,
-				void *object, CK_ATTRIBUTE_PTR attr)
-{
-	struct pkcs11_secret_key *key;
-
-	key = (struct pkcs11_secret_key *) object;
-	switch (attr->type) {
-	case CKA_CLASS:
-		get_attr(attr, CK_OBJECT_CLASS, CKO_SECRET_KEY);
-		break;
-	case CKA_KEY_TYPE:
-		get_attr(attr, CK_KEY_TYPE, key->type);
-	case CKA_VALUE:
-		check_attr(attr, key->value_len);
-		memcpy(attr->pValue, key->value, key->value_len);
-		break;
-	case CKA_VALUE_LEN:
-		get_attr(attr, CK_ULONG, key->value_len);
-		break;
-	case CKA_SENSITIVE:
-	case CKA_SIGN:
-	case CKA_VERIFY:
-	case CKA_WRAP:
-	case CKA_UNWRAP:
-	case CKA_NEVER_EXTRACTABLE:
-		get_attr(attr, CK_BBOOL, 0);
-		break;
-	case CKA_ENCRYPT:
-	case CKA_DECRYPT:
-	case CKA_EXTRACTABLE:
-	case CKA_ALWAYS_SENSITIVE:
-		get_attr(attr, CK_BBOOL, 1);
-		break;
-	default:
-		return CKR_ATTRIBUTE_TYPE_INVALID;
-	}
-	return CKR_OK;
-}
-
-struct sc_pkcs11_object_ops pkcs11_secret_key_ops = {
-	sc_pkcs11_secret_key_release,
-	sc_pkcs11_secret_key_set_attribute,
-	sc_pkcs11_secret_key_get_attribute,
-	sc_pkcs11_any_cmp_attribute,
-	NULL,	/* destroy_object */
-	NULL,	/* get_size */
-	NULL,	/* sign */
-	NULL,	/* unwrap_key */
-	NULL	/* decrypt */
-};
diff --git a/src/tools/pkcs15-init.c b/src/tools/pkcs15-init.c
index b90d8e7..8e69344 100644
--- a/src/tools/pkcs15-init.c
+++ b/src/tools/pkcs15-init.c
@@ -107,7 +107,6 @@ static int	get_key_callback(struct sc_profile *,
 			int method, int reference,
 			const u8 *, size_t, u8 *, size_t *);
 
-static int	do_generate_key_soft(int, unsigned int, EVP_PKEY **);
 static int	do_read_private_key(const char *, const char *,
 				EVP_PKEY **, X509 **, unsigned int);
 static int	do_read_public_key(const char *, const char *, EVP_PKEY **);
@@ -124,7 +123,6 @@ enum {
 	OPT_EXTRACTABLE,
 	OPT_UNPROTECTED,
 	OPT_AUTHORITY,
-	OPT_SOFT_KEYGEN,
 	OPT_ASSERT_PRISTINE,
 	OPT_SECRET,
 	OPT_PUBKEY_LABEL,
@@ -183,7 +181,6 @@ const struct option	options[] = {
 
 	{ "extractable",	no_argument, NULL,		OPT_EXTRACTABLE },
 	{ "insecure",		no_argument, NULL,		OPT_UNPROTECTED },
-	{ "soft",		no_argument, NULL,		OPT_SOFT_KEYGEN },
 	{ "use-default-transport-keys",
 				no_argument, NULL,		'T' },
 	{ "no-prompt",		no_argument, NULL,		OPT_NO_PROMPT },
@@ -239,7 +236,6 @@ static const char *		option_help[] = {
 
 	"Private key stored as an extractable key",
 	"Insecure mode: do not require PIN/passphrase for private key",
-	"Use software key generation, even if the card supports on-board key generation",
 	"Do not ask for transport keys if the driver thinks it knows the key",
 	"Do not prompt the user; if no PINs supplied, pinpad will be used",
 
@@ -314,7 +310,6 @@ static unsigned int		opt_actions;
 static int			opt_extractable = 0,
 				opt_unprotected = 0,
 				opt_authority = 0,
-				opt_softkeygen = 0,
 				opt_no_prompt = 0,
 				opt_no_sopin = 0,
 				opt_use_defkeys = 0,
@@ -1385,8 +1380,7 @@ static int
 do_generate_key(struct sc_profile *profile, const char *spec)
 {
 	struct sc_pkcs15init_keygen_args keygen_args;
-	unsigned int	evp_algo, keybits = 1024;
-	EVP_PKEY	*pkey;
+	unsigned int keybits = 1024;
 	int		r;
 
 	memset(&keygen_args, 0, sizeof(keygen_args));
@@ -1399,11 +1393,9 @@ do_generate_key(struct sc_profile *profile, const char *spec)
 	/* Parse the key spec given on the command line */
 	if (!strncasecmp(spec, "rsa", 3)) {
 		keygen_args.prkey_args.key.algorithm = SC_ALGORITHM_RSA;
-		evp_algo = EVP_PKEY_RSA;
 		spec += 3;
 	} else if (!strncasecmp(spec, "dsa", 3)) {
 		keygen_args.prkey_args.key.algorithm = SC_ALGORITHM_DSA;
-		evp_algo = EVP_PKEY_DSA;
 		spec += 3;
 	} else if (!strncasecmp(spec, "gost2001", strlen("gost2001"))) {
 		keygen_args.prkey_args.key.algorithm = SC_ALGORITHM_GOSTR3410;
@@ -1411,7 +1403,6 @@ do_generate_key(struct sc_profile *profile, const char *spec)
 		/* FIXME: now only SC_PKCS15_PARAMSET_GOSTR3410_A */
 		keygen_args.prkey_args.gost_params.gostr3410 =
 			SC_PKCS15_PARAMSET_GOSTR3410_A;
-		evp_algo = 0; /* FIXME */
 		spec += strlen("gost2001");
 	} else {
 		util_error("Unknown algorithm \"%s\"", spec);
@@ -1430,31 +1421,9 @@ do_generate_key(struct sc_profile *profile, const char *spec)
 		}
 	}
 
-	if (!opt_softkeygen) {
-		r = sc_pkcs15init_generate_key(p15card, profile, &keygen_args,
-			keybits, NULL);
-		if (r >= 0 || r != SC_ERROR_NOT_SUPPORTED)
-			return r;
-		if (verbose)
-			printf("Warning: card doesn't support on-board "
-			       "key generation.\n"
-			       "Trying software generation\n");
-	}
-
-	/* Generate the key ourselves */
-	if ((r = do_generate_key_soft(evp_algo, keybits, &pkey)) < 0
-	 || (r = do_convert_private_key(&keygen_args.prkey_args.key, pkey) ) < 0)
-		goto out;
-
-	r = sc_pkcs15init_store_private_key(p15card,
-			profile, &keygen_args.prkey_args, NULL);
-
-	/* Store public key portion on card */
-	if (r >= 0)
-		r = do_store_public_key(profile, pkey);
-
-out:
-	EVP_PKEY_free(pkey);
+	r = sc_pkcs15init_generate_key(p15card, profile, &keygen_args, keybits, NULL);
+	if (r >= 0 || r != SC_ERROR_NOT_SUPPORTED)
+		fprintf(stderr, "Card doesn't support on-board key generation!");
 	return r;
 }
 
@@ -1816,46 +1785,6 @@ use_default_key:
 }
 
 /*
- * Generate a private key
- */
-static int do_generate_key_soft(int algorithm, unsigned int bits,
-		EVP_PKEY **res)
-{
-	*res = EVP_PKEY_new();
-	switch (algorithm) {
-	case EVP_PKEY_RSA: {
-			RSA	*rsa;
-			BIO	*err;
-
-			err = BIO_new(BIO_s_mem());
-			rsa = RSA_generate_key(bits, 0x10001, NULL, err);
-			BIO_free(err);
-			if (rsa == 0)
-				util_fatal("RSA key generation error");
-			EVP_PKEY_assign_RSA(*res, rsa);
-			break;
-		}
-	case EVP_PKEY_DSA: {
-			DSA	*dsa;
-			int	r = 0;
-
-			dsa = DSA_generate_parameters(bits,
-					NULL, 0, NULL,
-					NULL, NULL, NULL);
-			if (dsa)
-				r = DSA_generate_key(dsa);
-			if (r == 0 || dsa == 0)
-				util_fatal("DSA key generation error");
-			EVP_PKEY_assign_DSA(*res, dsa);
-			break;
-		}
-	default:
-		util_fatal("Unable to generate key: unsupported algorithm");
-	}
-	return 0;
-}
-
-/*
  * Read a private key
  */
 static int pass_cb(char *buf, int len, int flags, void *d)
@@ -2574,9 +2503,6 @@ handle_option(const struct option *opt)
 	case OPT_AUTHORITY:
 		opt_authority = 1;
 		break;
-	case OPT_SOFT_KEYGEN:
-		opt_softkeygen = 1;
-		break;
 	case OPT_APPLICATION_NAME:
 		opt_application_name = optarg;
 		break;
