- (djm) [authfd.c authfile.c bufec.c buffer.h configure.ac kex.h kexecdh.c]
   [kexecdhc.c kexecdhs.c key.c key.h myproposal.h packet.c readconf.c]
   [ssh-agent.c ssh-ecdsa.c ssh-keygen.c ssh.c] Disable ECDH and ECDSA on
   platforms that don't have the requisite OpenSSL support. ok dtucker@
diff --git a/ChangeLog b/ChangeLog
index 87fee3b..742e966 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -62,6 +62,10 @@
      client.
      
      ok naddy@
+ - (djm) [authfd.c authfile.c bufec.c buffer.h configure.ac kex.h kexecdh.c]
+   [kexecdhc.c kexecdhs.c key.c key.h myproposal.h packet.c readconf.c]
+   [ssh-agent.c ssh-ecdsa.c ssh-keygen.c ssh.c] Disable ECDH and ECDSA on
+   platforms that don't have the requisite OpenSSL support. ok dtucker@
 
 20100831
  - OpenBSD CVS Sync
diff --git a/authfd.c b/authfd.c
index ec537d2..c11c3f5 100644
--- a/authfd.c
+++ b/authfd.c
@@ -509,6 +509,7 @@
 		    buffer_len(&key->cert->certblob));
 		buffer_put_bignum2(b, key->dsa->priv_key);
 		break;
+#ifdef OPENSSL_HAS_ECC
 	case KEY_ECDSA:
 		buffer_put_cstring(b, key_curve_nid_to_name(key->ecdsa_nid));
 		buffer_put_ecpoint(b, EC_KEY_get0_group(key->ecdsa),
@@ -522,6 +523,7 @@
 		    buffer_len(&key->cert->certblob));
 		buffer_put_bignum2(b, EC_KEY_get0_private_key(key->ecdsa));
 		break;
+#endif
 	}
 	buffer_put_cstring(b, comment);
 }
diff --git a/authfile.c b/authfile.c
index 20ac8c7..b1e3eda 100644
--- a/authfile.c
+++ b/authfile.c
@@ -213,10 +213,12 @@
 		success = PEM_write_DSAPrivateKey(fp, key->dsa,
 		    cipher, passphrase, len, NULL, NULL);
 		break;
+#ifdef OPENSSL_HAS_ECC
 	case KEY_ECDSA:
 		success = PEM_write_ECPrivateKey(fp, key->ecdsa,
 		    cipher, passphrase, len, NULL, NULL);
 		break;
+#endif
 	case KEY_RSA:
 		success = PEM_write_RSAPrivateKey(fp, key->rsa,
 		    cipher, passphrase, len, NULL, NULL);
@@ -515,6 +517,7 @@
 #ifdef DEBUG_PK
 		DSA_print_fp(stderr, prv->dsa, 8);
 #endif
+#ifdef OPENSSL_HAS_ECC
 	} else if (pk->type == EVP_PKEY_EC &&
 	    (type == KEY_UNSPEC||type==KEY_ECDSA)) {
 		prv = key_new(KEY_UNSPEC);
@@ -538,6 +541,7 @@
 		if (prv->ecdsa != NULL)
 			key_dump_ec_key(prv->ecdsa);
 #endif
+#endif /* OPENSSL_HAS_ECC */
 	} else {
 		error("PEM_read_PrivateKey: mismatch or "
 		    "unknown EVP_PKEY save_type %d", pk->save_type);
diff --git a/bufec.c b/bufec.c
index c77d1ec..3dcb494 100644
--- a/bufec.c
+++ b/bufec.c
@@ -17,6 +17,8 @@
 
 #include "includes.h"
 
+#ifdef OPENSSL_HAS_ECC
+
 #include <sys/types.h>
 
 #include <openssl/bn.h>
@@ -141,3 +143,4 @@
 		fatal("%s: buffer error", __func__);
 }
 
+#endif /* OPENSSL_HAS_ECC */
diff --git a/buffer.h b/buffer.h
index 1fb3f16..e2a9dd1 100644
--- a/buffer.h
+++ b/buffer.h
@@ -86,11 +86,13 @@
 void	*buffer_get_string_ptr_ret(Buffer *, u_int *);
 int	buffer_get_char_ret(char *, Buffer *);
 
+#ifdef OPENSSL_HAS_ECC
 #include <openssl/ec.h>
 
 int	buffer_put_ecpoint_ret(Buffer *, const EC_GROUP *, const EC_POINT *);
 void	buffer_put_ecpoint(Buffer *, const EC_GROUP *, const EC_POINT *);
 int	buffer_get_ecpoint_ret(Buffer *, const EC_GROUP *, EC_POINT *);
 void	buffer_get_ecpoint(Buffer *, const EC_GROUP *, EC_POINT *);
+#endif
 
 #endif				/* BUFFER_H */
diff --git a/configure.ac b/configure.ac
index 637e7b5..d267ba2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,4 +1,4 @@
-# $Id: configure.ac,v 1.451 2010/08/16 03:15:23 dtucker Exp $
+# $Id: configure.ac,v 1.452 2010/09/10 01:39:27 djm Exp $
 #
 # Copyright (c) 1999-2004 Damien Miller
 #
@@ -15,7 +15,7 @@
 # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
 AC_INIT(OpenSSH, Portable, openssh-unix-dev@mindrot.org)
-AC_REVISION($Revision: 1.451 $)
+AC_REVISION($Revision: 1.452 $)
 AC_CONFIG_SRCDIR([ssh.c])
 
 AC_CONFIG_HEADER(config.h)
@@ -2158,6 +2158,28 @@
 # Search for SHA256 support in libc and/or OpenSSL
 AC_CHECK_FUNCS(SHA256_Update EVP_sha256)
 
+# Check complete ECC support in OpenSSL
+AC_MSG_CHECKING([whether OpenSSL has complete ECC support])
+AC_LINK_IFELSE(
+	[AC_LANG_SOURCE([[
+#include <openssl/ec.h>
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+int main(void) {
+	EC_KEY *e = EC_KEY_new_by_curve_name(NID_secp521r1);
+	const EVP_MD *m = EVP_sha512(); /* We need this too */
+}
+	]])],
+	[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(OPENSSL_HAS_ECC, 1,
+		    [libcrypto includes complete ECC support])
+	],
+	[
+		AC_MSG_RESULT(no)
+	]
+)
+
 saved_LIBS="$LIBS"
 AC_CHECK_LIB(iaf, ia_openinfo, [
 	LIBS="$LIBS -liaf"
diff --git a/kex.h b/kex.h
index f5dcc87..0691475 100644
--- a/kex.h
+++ b/kex.h
@@ -159,13 +159,16 @@
 kexgex_hash(const EVP_MD *, char *, char *, char *, int, char *,
     int, u_char *, int, int, int, int, BIGNUM *, BIGNUM *, BIGNUM *,
     BIGNUM *, BIGNUM *, u_char **, u_int *);
+#ifdef OPENSSL_HAS_ECC
 void
 kex_ecdh_hash(const EVP_MD *, const EC_GROUP *, char *, char *, char *, int,
     char *, int, u_char *, int, const EC_POINT *, const EC_POINT *,
     const BIGNUM *, u_char **, u_int *);
-
 int	kex_ecdh_name_to_nid(const char *);
 const EVP_MD *kex_ecdh_name_to_evpmd(const char *);
+#else
+# define kex_ecdh_name_to_evpmd(x) NULL
+#endif
 
 void
 derive_ssh1_session_id(BIGNUM *, BIGNUM *, u_int8_t[8], u_int8_t[16]);
diff --git a/kexecdh.c b/kexecdh.c
index f59d7b9..4c58a51 100644
--- a/kexecdh.c
+++ b/kexecdh.c
@@ -26,6 +26,8 @@
 
 #include "includes.h"
 
+#ifdef OPENSSL_HAS_ECC
+
 #include <sys/types.h>
 
 #include <signal.h>
@@ -116,3 +118,4 @@
 	*hashlen = EVP_MD_size(evp_md);
 }
 
+#endif /* OPENSSL_HAS_ECC */
diff --git a/kexecdhc.c b/kexecdhc.c
index 7ac7b1e..297a0e5 100644
--- a/kexecdhc.c
+++ b/kexecdhc.c
@@ -32,8 +32,6 @@
 #include <string.h>
 #include <signal.h>
 
-#include <openssl/ecdh.h>
-
 #include "xmalloc.h"
 #include "buffer.h"
 #include "key.h"
@@ -44,6 +42,10 @@
 #include "dh.h"
 #include "ssh2.h"
 
+#ifdef OPENSSL_HAS_ECC
+
+#include <openssl/ecdh.h>
+
 void
 kexecdh_client(Kex *kex)
 {
@@ -156,3 +158,10 @@
 	BN_clear_free(shared_secret);
 	kex_finish(kex);
 }
+#else /* OPENSSL_HAS_ECC */
+void
+kexecdh_client(Kex *kex)
+{
+	fatal("ECC support is not enabled");
+}
+#endif /* OPENSSL_HAS_ECC */
diff --git a/kexecdhs.c b/kexecdhs.c
index e49a0ef..d2c3feb 100644
--- a/kexecdhs.c
+++ b/kexecdhs.c
@@ -30,8 +30,6 @@
 #include <string.h>
 #include <signal.h>
 
-#include <openssl/ecdh.h>
-
 #include "xmalloc.h"
 #include "buffer.h"
 #include "key.h"
@@ -46,6 +44,10 @@
 #endif
 #include "monitor_wrap.h"
 
+#ifdef OPENSSL_HAS_ECC
+
+#include <openssl/ecdh.h>
+
 void
 kexecdh_server(Kex *kex)
 {
@@ -161,3 +163,10 @@
 	BN_clear_free(shared_secret);
 	kex_finish(kex);
 }
+#else /* OPENSSL_HAS_ECC */
+void
+kexecdh_server(Kex *kex)
+{
+	fatal("ECC support is not enabled");
+}
+#endif /* OPENSSL_HAS_ECC */
diff --git a/key.c b/key.c
index b9dc235..3cda8f2 100644
--- a/key.c
+++ b/key.c
@@ -111,10 +111,12 @@
 			fatal("key_new: BN_new failed");
 		k->dsa = dsa;
 		break;
+#ifdef OPENSSL_HAS_ECC
 	case KEY_ECDSA:
 	case KEY_ECDSA_CERT:
 		/* Cannot do anything until we know the group */
 		break;
+#endif
 	case KEY_UNSPEC:
 		break;
 	default:
@@ -214,12 +216,14 @@
 			DSA_free(k->dsa);
 		k->dsa = NULL;
 		break;
+#ifdef OPENSSL_HAS_ECC
 	case KEY_ECDSA:
 	case KEY_ECDSA_CERT:
 		if (k->ecdsa != NULL)
 			EC_KEY_free(k->ecdsa);
 		k->ecdsa = NULL;
 		break;
+#endif
 	case KEY_UNSPEC:
 		break;
 	default:
@@ -279,6 +283,7 @@
 		    BN_cmp(a->dsa->q, b->dsa->q) == 0 &&
 		    BN_cmp(a->dsa->g, b->dsa->g) == 0 &&
 		    BN_cmp(a->dsa->pub_key, b->dsa->pub_key) == 0;
+#ifdef OPENSSL_HAS_ECC
 	case KEY_ECDSA_CERT:
 	case KEY_ECDSA:
 		if (a->ecdsa == NULL || b->ecdsa == NULL ||
@@ -297,6 +302,7 @@
 		}
 		BN_CTX_free(bnctx);
 		return 1;
+#endif /* OPENSSL_HAS_ECC */
 	default:
 		fatal("key_equal: bad key type %d", a->type);
 	}
@@ -695,11 +701,13 @@
 		}
 		*space = '\0';
 		type = key_type_from_name(cp);
+#ifdef OPENSSL_HAS_ECC
 		if (key_type_plain(type) == KEY_ECDSA &&
 		    (curve_nid = key_ecdsa_nid_from_name(cp)) == -1) {
 			debug("key_read: invalid curve");
 			return -1;
 		}
+#endif
 		*space = ' ';
 		if (type == KEY_UNSPEC) {
 			debug3("key_read: missing keytype");
@@ -736,12 +744,14 @@
 			key_free(k);
 			return -1;
 		}
+#ifdef OPENSSL_HAS_ECC
 		if (key_type_plain(type) == KEY_ECDSA &&
 		    curve_nid != k->ecdsa_nid) {
 			error("key_read: type mismatch: EC curve mismatch");
 			key_free(k);
 			return -1;
 		}
+#endif
 /*XXXX*/
 		if (key_is_cert(ret)) {
 			if (!key_is_cert(k)) {
@@ -772,6 +782,7 @@
 			DSA_print_fp(stderr, ret->dsa, 8);
 #endif
 		}
+#ifdef OPENSSL_HAS_ECC
 		if (key_type_plain(ret->type) == KEY_ECDSA) {
 			if (ret->ecdsa != NULL)
 				EC_KEY_free(ret->ecdsa);
@@ -783,6 +794,7 @@
 			key_dump_ec_key(ret->ecdsa);
 #endif
 		}
+#endif
 		success = 1;
 /*XXXX*/
 		key_free(k);
@@ -839,11 +851,13 @@
 		if (key->dsa == NULL)
 			return 0;
 		break;
+#ifdef OPENSSL_HAS_ECC
 	case KEY_ECDSA:
 	case KEY_ECDSA_CERT:
 		if (key->ecdsa == NULL)
 			return 0;
 		break;
+#endif
 	case KEY_RSA:
 	case KEY_RSA_CERT_V00:
 	case KEY_RSA_CERT:
@@ -877,8 +891,10 @@
 		return "RSA";
 	case KEY_DSA:
 		return "DSA";
+#ifdef OPENSSL_HAS_ECC
 	case KEY_ECDSA:
 		return "ECDSA";
+#endif
 	case KEY_RSA_CERT_V00:
 		return "RSA-CERT-V00";
 	case KEY_DSA_CERT_V00:
@@ -887,8 +903,10 @@
 		return "RSA-CERT";
 	case KEY_DSA_CERT:
 		return "DSA-CERT";
+#ifdef OPENSSL_HAS_ECC
 	case KEY_ECDSA_CERT:
 		return "ECDSA-CERT";
+#endif
 	}
 	return "unknown";
 }
@@ -922,6 +940,7 @@
 		return "ssh-rsa-cert-v01@openssh.com";
 	case KEY_DSA_CERT:
 		return "ssh-dss-cert-v01@openssh.com";
+#ifdef OPENSSL_HAS_ECC
 	case KEY_ECDSA:
 		switch (nid) {
 		case NID_X9_62_prime256v1:
@@ -946,6 +965,7 @@
 			break;
 		}
 		break;
+#endif /* OPENSSL_HAS_ECC */
 	}
 	return "ssh-unknown";
 }
@@ -976,9 +996,11 @@
 	case KEY_DSA_CERT_V00:
 	case KEY_DSA_CERT:
 		return BN_num_bits(k->dsa->p);
+#ifdef OPENSSL_HAS_ECC
 	case KEY_ECDSA:
 	case KEY_ECDSA_CERT:
 		return key_curve_nid_to_bits(k->ecdsa_nid);
+#endif
 	}
 	return 0;
 }
@@ -1012,17 +1034,20 @@
 key_ecdsa_bits_to_nid(int bits)
 {
 	switch (bits) {
+#ifdef OPENSSL_HAS_ECC
 	case 256:
 		return NID_X9_62_prime256v1;
 	case 384:
 		return NID_secp384r1;
 	case 521:
 		return NID_secp521r1;
+#endif
 	default:
 		return -1;
 	}
 }
 
+#ifdef OPENSSL_HAS_ECC
 /*
  * This is horrid, but OpenSSL's PEM_read_PrivateKey seems not to restore
  * the EC_GROUP nid when loading a key...
@@ -1070,6 +1095,7 @@
 		fatal("%s: EC_KEY_generate_key failed", __func__);
 	return private;
 }
+#endif /* OPENSSL_HAS_ECC */
 
 Key *
 key_generate(int type, u_int bits)
@@ -1079,9 +1105,11 @@
 	case KEY_DSA:
 		k->dsa = dsa_generate_private_key(bits);
 		break;
+#ifdef OPENSSL_HAS_ECC
 	case KEY_ECDSA:
 		k->ecdsa = ecdsa_generate_private_key(bits, &k->ecdsa_nid);
 		break;
+#endif
 	case KEY_RSA:
 	case KEY_RSA1:
 		k->rsa = rsa_generate_private_key(bits);
@@ -1158,6 +1186,7 @@
 		    (BN_copy(n->dsa->pub_key, k->dsa->pub_key) == NULL))
 			fatal("key_from_private: BN_copy failed");
 		break;
+#ifdef OPENSSL_HAS_ECC
 	case KEY_ECDSA:
 	case KEY_ECDSA_CERT:
 		n = key_new(k->type);
@@ -1168,6 +1197,7 @@
 		    EC_KEY_get0_public_key(k->ecdsa)) != 1)
 			fatal("%s: EC_KEY_set_public_key failed", __func__);
 		break;
+#endif
 	case KEY_RSA:
 	case KEY_RSA1:
 	case KEY_RSA_CERT_V00:
@@ -1199,11 +1229,13 @@
 		return KEY_RSA;
 	} else if (strcmp(name, "ssh-dss") == 0) {
 		return KEY_DSA;
+#ifdef OPENSSL_HAS_ECC
 	} else if (strcmp(name, "ecdsa") == 0 ||
 	    strcmp(name, "ecdsa-sha2-nistp256") == 0 ||
 	    strcmp(name, "ecdsa-sha2-nistp384") == 0 ||
 	    strcmp(name, "ecdsa-sha2-nistp521") == 0) {
 		return KEY_ECDSA;
+#endif
 	} else if (strcmp(name, "ssh-rsa-cert-v00@openssh.com") == 0) {
 		return KEY_RSA_CERT_V00;
 	} else if (strcmp(name, "ssh-dss-cert-v00@openssh.com") == 0) {
@@ -1212,10 +1244,13 @@
 		return KEY_RSA_CERT;
 	} else if (strcmp(name, "ssh-dss-cert-v01@openssh.com") == 0) {
 		return KEY_DSA_CERT;
+#ifdef OPENSSL_HAS_ECC
 	} else if (strcmp(name, "ecdsa-sha2-nistp256-cert-v01@openssh.com") == 0 ||
 	    strcmp(name, "ecdsa-sha2-nistp384-cert-v01@openssh.com") == 0 ||
-	    strcmp(name, "ecdsa-sha2-nistp521-cert-v01@openssh.com") == 0)
+	    strcmp(name, "ecdsa-sha2-nistp521-cert-v01@openssh.com") == 0) {
 		return KEY_ECDSA_CERT;
+#endif
+	}
 
 	debug2("key_type_from_name: unknown key type '%s'", name);
 	return KEY_UNSPEC;
@@ -1224,6 +1259,7 @@
 int
 key_ecdsa_nid_from_name(const char *name)
 {
+#ifdef OPENSSL_HAS_ECC
 	if (strcmp(name, "ecdsa-sha2-nistp256") == 0 ||
 	    strcmp(name, "ecdsa-sha2-nistp256-cert-v01@openssh.com") == 0)
 		return NID_X9_62_prime256v1;
@@ -1233,6 +1269,7 @@
 	if (strcmp(name, "ecdsa-sha2-nistp521") == 0 ||
 	    strcmp(name, "ecdsa-sha2-nistp521-cert-v01@openssh.com") == 0)
 		return NID_secp521r1;
+#endif /* OPENSSL_HAS_ECC */
 
 	debug2("%s: unknown/non-ECDSA key type '%s'", __func__, name);
 	return -1;
@@ -1403,7 +1440,9 @@
 	int rlen, type, nid = -1;
 	char *ktype = NULL, *curve = NULL;
 	Key *key = NULL;
+#ifdef OPENSSL_HAS_ECC
 	EC_POINT *q = NULL;
+#endif
 
 #ifdef DEBUG_PK
 	dump_base64(stderr, blob, blen);
@@ -1416,8 +1455,10 @@
 	}
 
 	type = key_type_from_name(ktype);
+#ifdef OPENSSL_HAS_ECC
 	if (key_type_plain(type) == KEY_ECDSA)
 		nid = key_ecdsa_nid_from_name(ktype);
+#endif
 
 	switch (type) {
 	case KEY_RSA_CERT:
@@ -1455,6 +1496,7 @@
 		DSA_print_fp(stderr, key->dsa, 8);
 #endif
 		break;
+#ifdef OPENSSL_HAS_ECC
 	case KEY_ECDSA_CERT:
 		(void)buffer_get_string_ptr_ret(&b, NULL); /* Skip nonce */
 		/* FALLTHROUGH */
@@ -1490,6 +1532,7 @@
 		key_dump_ec_point(EC_KEY_get0_group(key->ecdsa), q);
 #endif
 		break;
+#endif /* OPENSSL_HAS_ECC */
 	case KEY_UNSPEC:
 		key = key_new(type);
 		break;
@@ -1509,8 +1552,10 @@
 		xfree(ktype);
 	if (curve != NULL)
 		xfree(curve);
+#ifdef OPENSSL_HAS_ECC
 	if (q != NULL)
 		EC_POINT_free(q);
+#endif
 	buffer_free(&b);
 	return key;
 }
@@ -1543,12 +1588,14 @@
 		buffer_put_bignum2(&b, key->dsa->g);
 		buffer_put_bignum2(&b, key->dsa->pub_key);
 		break;
+#ifdef OPENSSL_HAS_ECC
 	case KEY_ECDSA:
 		buffer_put_cstring(&b, key_ssh_name(key));
 		buffer_put_cstring(&b, key_curve_nid_to_name(key->ecdsa_nid));
 		buffer_put_ecpoint(&b, EC_KEY_get0_group(key->ecdsa),
 		    EC_KEY_get0_public_key(key->ecdsa));
 		break;
+#endif
 	case KEY_RSA:
 		buffer_put_cstring(&b, key_ssh_name(key));
 		buffer_put_bignum2(&b, key->rsa->e);
@@ -1582,9 +1629,11 @@
 	case KEY_DSA_CERT:
 	case KEY_DSA:
 		return ssh_dss_sign(key, sigp, lenp, data, datalen);
+#ifdef OPENSSL_HAS_ECC
 	case KEY_ECDSA_CERT:
 	case KEY_ECDSA:
 		return ssh_ecdsa_sign(key, sigp, lenp, data, datalen);
+#endif
 	case KEY_RSA_CERT_V00:
 	case KEY_RSA_CERT:
 	case KEY_RSA:
@@ -1613,9 +1662,11 @@
 	case KEY_DSA_CERT:
 	case KEY_DSA:
 		return ssh_dss_verify(key, signature, signaturelen, data, datalen);
+#ifdef OPENSSL_HAS_ECC
 	case KEY_ECDSA_CERT:
 	case KEY_ECDSA:
 		return ssh_ecdsa_verify(key, signature, signaturelen, data, datalen);
+#endif
 	case KEY_RSA_CERT_V00:
 	case KEY_RSA_CERT:
 	case KEY_RSA:
@@ -1670,6 +1721,7 @@
 		if ((pk->dsa->pub_key = BN_dup(k->dsa->pub_key)) == NULL)
 			fatal("key_demote: BN_dup failed");
 		break;
+#ifdef OPENSSL_HAS_ECC
 	case KEY_ECDSA_CERT:
 		key_cert_copy(k, pk);
 		/* FALLTHROUGH */
@@ -1680,6 +1732,7 @@
 		    EC_KEY_get0_public_key(k->ecdsa)) != 1)
 			fatal("key_demote: EC_KEY_set_public_key failed");
 		break;
+#endif
 	default:
 		fatal("key_free: bad key type %d", k->type);
 		break;
@@ -1819,6 +1872,7 @@
 		buffer_put_bignum2(&k->cert->certblob, k->dsa->g);
 		buffer_put_bignum2(&k->cert->certblob, k->dsa->pub_key);
 		break;
+#ifdef OPENSSL_HAS_ECC
 	case KEY_ECDSA_CERT:
 		buffer_put_cstring(&k->cert->certblob,
 		    key_curve_nid_to_name(k->ecdsa_nid));
@@ -1826,6 +1880,7 @@
 		    EC_KEY_get0_group(k->ecdsa),
 		    EC_KEY_get0_public_key(k->ecdsa));
 		break;
+#endif
 	case KEY_RSA_CERT_V00:
 	case KEY_RSA_CERT:
 		buffer_put_bignum2(&k->cert->certblob, k->rsa->e);
@@ -1955,12 +2010,14 @@
 int
 key_curve_name_to_nid(const char *name)
 {
+#ifdef OPENSSL_HAS_ECC
 	if (strcmp(name, "nistp256") == 0)
 		return NID_X9_62_prime256v1;
 	else if (strcmp(name, "nistp384") == 0)
 		return NID_secp384r1;
 	else if (strcmp(name, "nistp521") == 0)
 		return NID_secp521r1;
+#endif
 
 	debug("%s: unsupported EC curve name \"%.100s\"", __func__, name);
 	return -1;
@@ -1970,12 +2027,14 @@
 key_curve_nid_to_bits(int nid)
 {
 	switch (nid) {
+#ifdef OPENSSL_HAS_ECC
 	case NID_X9_62_prime256v1:
 		return 256;
 	case NID_secp384r1:
 		return 384;
 	case NID_secp521r1:
 		return 521;
+#endif
 	default:
 		error("%s: unsupported EC curve nid %d", __func__, nid);
 		return 0;
@@ -1985,17 +2044,19 @@
 const char *
 key_curve_nid_to_name(int nid)
 {
+#ifdef OPENSSL_HAS_ECC
 	if (nid == NID_X9_62_prime256v1)
 		return "nistp256";
 	else if (nid == NID_secp384r1)
 		return "nistp384";
 	else if (nid == NID_secp521r1)
 		return "nistp521";
-
+#endif
 	error("%s: unsupported EC curve nid %d", __func__, nid);
 	return NULL;
 }
 
+#ifdef OPENSSL_HAS_ECC
 const EVP_MD *
 key_ec_nid_to_evpmd(int nid)
 {
@@ -2180,4 +2241,4 @@
 	fputs("\n", stderr);
 }
 #endif /* defined(DEBUG_KEXECDH) || defined(DEBUG_PK) */
-
+#endif /* OPENSSL_HAS_ECC */
diff --git a/key.h b/key.h
index ba1a20c..86a1d88 100644
--- a/key.h
+++ b/key.h
@@ -29,7 +29,9 @@
 #include "buffer.h"
 #include <openssl/rsa.h>
 #include <openssl/dsa.h>
+#ifdef OPENSSL_HAS_ECC
 #include <openssl/ec.h>
+#endif
 
 typedef struct Key Key;
 enum types {
@@ -77,7 +79,11 @@
 	RSA	*rsa;
 	DSA	*dsa;
 	int	 ecdsa_nid;	/* NID of curve */
+#ifdef OPENSSL_HAS_ECC
 	EC_KEY	*ecdsa;
+#else
+	void	*ecdsa;
+#endif
 	struct KeyCert *cert;
 };
 
@@ -114,10 +120,12 @@
 const char *	 key_curve_nid_to_name(int);
 u_int		 key_curve_nid_to_bits(int);
 int		 key_ecdsa_bits_to_nid(int);
+#ifdef OPENSSL_HAS_ECC
 int		 key_ecdsa_group_to_nid(const EC_GROUP *);
 const EVP_MD *	 key_ec_nid_to_evpmd(int nid);
 int		 key_ec_validate_public(const EC_GROUP *, const EC_POINT *);
 int		 key_ec_validate_private(const EC_KEY *);
+#endif
 
 Key		*key_from_blob(const u_char *, u_int);
 int		 key_to_blob(const Key *, u_char **, u_int *);
@@ -135,7 +143,7 @@
 int	 ssh_rsa_sign(const Key *, u_char **, u_int *, const u_char *, u_int);
 int	 ssh_rsa_verify(const Key *, const u_char *, u_int, const u_char *, u_int);
 
-#if defined(DEBUG_KEXECDH) || defined(DEBUG_PK)
+#if defined(OPENSSL_HAS_ECC) && (defined(DEBUG_KEXECDH) || defined(DEBUG_PK))
 void	key_dump_ec_point(const EC_GROUP *, const EC_POINT *);
 void	key_dump_ec_key(const EC_KEY *);
 #endif
diff --git a/myproposal.h b/myproposal.h
index 5daca53..8931907 100644
--- a/myproposal.h
+++ b/myproposal.h
@@ -26,44 +26,49 @@
 
 #include <openssl/opensslv.h>
 
-/* Old OpenSSL doesn't support what we need for DHGEX-sha256 */
-#if OPENSSL_VERSION_NUMBER < 0x00907000L
-# define KEX_DEFAULT_KEX		\
-	"diffie-hellman-group-exchange-sha1," \
-	"diffie-hellman-group14-sha1," \
-	"diffie-hellman-group1-sha1"
-
-#define	KEX_DEFAULT_PK_ALG	\
-	"ssh-rsa-cert-v01@openssh.com," \
-	"ssh-dss-cert-v01@openssh.com," \
-	"ssh-rsa-cert-v00@openssh.com," \
-	"ssh-dss-cert-v00@openssh.com," \
-	"ssh-rsa," \
-	"ssh-dss"
-#else
-# define KEX_DEFAULT_KEX		\
+#ifdef OPENSSL_HAS_ECC
+# define KEX_ECDH_METHODS \
 	"ecdh-sha2-nistp256," \
 	"ecdh-sha2-nistp384," \
-	"ecdh-sha2-nistp521," \
-	"diffie-hellman-group-exchange-sha256," \
+	"ecdh-sha2-nistp521,"
+# define HOSTKEY_ECDSA_CERT_METHODS \
+	"ecdsa-sha2-nistp256-cert-v01@openssh.com," \
+	"ecdsa-sha2-nistp384-cert-v01@openssh.com," \
+	"ecdsa-sha2-nistp521-cert-v01@openssh.com,"
+# define HOSTKEY_ECDSA_METHODS \
+	"ecdsa-sha2-nistp256," \
+	"ecdsa-sha2-nistp384," \
+	"ecdsa-sha2-nistp521,"
+#else
+# define KEX_ECDH_METHODS
+# define HOSTKEY_ECDSA_CERT_METHODS
+# define HOSTKEY_ECDSA_METHODS
+#endif
+
+/* Old OpenSSL doesn't support what we need for DHGEX-sha256 */
+#if OPENSSL_VERSION_NUMBER < 0x00907000L
+# define KEX_SHA256_METHODS \
+	"diffie-hellman-group-exchange-sha1,"
+#else
+# define KEX_SHA256_METHODS
+#endif
+
+# define KEX_DEFAULT_KEX \
+	KEX_ECDH_METHODS \
+	KEX_SHA256_METHODS \
 	"diffie-hellman-group-exchange-sha1," \
 	"diffie-hellman-group14-sha1," \
 	"diffie-hellman-group1-sha1"
 
 #define	KEX_DEFAULT_PK_ALG	\
-	"ecdsa-sha2-nistp256-cert-v01@openssh.com," \
-	"ecdsa-sha2-nistp384-cert-v01@openssh.com," \
-	"ecdsa-sha2-nistp521-cert-v01@openssh.com," \
+	HOSTKEY_ECDSA_CERT_METHODS \
 	"ssh-rsa-cert-v01@openssh.com," \
 	"ssh-dss-cert-v01@openssh.com," \
 	"ssh-rsa-cert-v00@openssh.com," \
 	"ssh-dss-cert-v00@openssh.com," \
-	"ecdsa-sha2-nistp256," \
-	"ecdsa-sha2-nistp384," \
-	"ecdsa-sha2-nistp521," \
+	HOSTKEY_ECDSA_METHODS \
 	"ssh-rsa," \
 	"ssh-dss"
-#endif
 
 #define	KEX_DEFAULT_ENCRYPT \
 	"aes128-ctr,aes192-ctr,aes256-ctr," \
diff --git a/packet.c b/packet.c
index a06c5e3..0018d58 100644
--- a/packet.c
+++ b/packet.c
@@ -641,11 +641,13 @@
 	buffer_put_bignum2(&active_state->outgoing_packet, value);
 }
 
+#ifdef OPENSSL_HAS_ECC
 void
 packet_put_ecpoint(const EC_GROUP *curve, const EC_POINT *point)
 {
 	buffer_put_ecpoint(&active_state->outgoing_packet, curve, point);
 }
+#endif
 
 /*
  * Finalizes and sends the packet.  If the encryption key has been set,
@@ -1517,11 +1519,13 @@
 	buffer_get_bignum2(&active_state->incoming_packet, value);
 }
 
+#ifdef OPENSSL_HAS_ECC
 void
 packet_get_ecpoint(const EC_GROUP *curve, EC_POINT *point)
 {
 	buffer_get_ecpoint(&active_state->incoming_packet, curve, point);
 }
+#endif
 
 void *
 packet_get_raw(u_int *length_ptr)
diff --git a/readconf.c b/readconf.c
index 98ce301..5864229 100644
--- a/readconf.c
+++ b/readconf.c
@@ -1214,12 +1214,13 @@
 			    xmalloc(len);
 			snprintf(options->identity_files[options->num_identity_files++],
 			    len, "~/%.100s", _PATH_SSH_CLIENT_ID_DSA);
-
+#ifdef OPENSSL_HAS_ECC
 			len = 2 + strlen(_PATH_SSH_CLIENT_ID_ECDSA) + 1;
 			options->identity_files[options->num_identity_files] =
 			    xmalloc(len);
 			snprintf(options->identity_files[options->num_identity_files++],
 			    len, "~/%.100s", _PATH_SSH_CLIENT_ID_ECDSA);
+#endif
 		}
 	}
 	if (options->escape_char == -1)
diff --git a/ssh-agent.c b/ssh-agent.c
index 87939b2..8f19fb1 100644
--- a/ssh-agent.c
+++ b/ssh-agent.c
@@ -468,8 +468,10 @@
 	int type, success = 0, death = 0, confirm = 0;
 	char *type_name, *comment, *curve;
 	Key *k = NULL;
+#ifdef OPENSSL_HAS_ECC
 	BIGNUM *exponent;
 	EC_POINT *q;
+#endif
 	u_char *cert;
 	u_int len;
 
@@ -510,6 +512,7 @@
 			key_add_private(k);
 			buffer_get_bignum2(&e->request, k->dsa->priv_key);
 			break;
+#ifdef OPENSSL_HAS_ECC
 		case KEY_ECDSA:
 			k = key_new_private(type);
 			k->ecdsa_nid = key_ecdsa_nid_from_name(type_name);
@@ -561,6 +564,7 @@
 				fatal("%s: bad ECDSA key", __func__);
 			BN_clear_free(exponent);
 			break;
+#endif /* OPENSSL_HAS_ECC */
 		case KEY_RSA:
 			k = key_new_private(type);
 			buffer_get_bignum2(&e->request, k->rsa->n);
diff --git a/ssh-ecdsa.c b/ssh-ecdsa.c
index 5c4ce23..c8276b4 100644
--- a/ssh-ecdsa.c
+++ b/ssh-ecdsa.c
@@ -26,6 +26,8 @@
 
 #include "includes.h"
 
+#ifdef OPENSSL_HAS_ECC
+
 #include <sys/types.h>
 
 #include <openssl/bn.h>
@@ -162,3 +164,5 @@
 	    ret == 1 ? "correct" : ret == 0 ? "incorrect" : "error");
 	return ret;
 }
+
+#endif /* OPENSSL_HAS_ECC */
diff --git a/ssh-keygen.c b/ssh-keygen.c
index 43b8c7f..bbd434b 100644
--- a/ssh-keygen.c
+++ b/ssh-keygen.c
@@ -265,10 +265,12 @@
 		if (!PEM_write_DSA_PUBKEY(stdout, k->dsa))
 			fatal("PEM_write_DSA_PUBKEY failed");
 		break;
+#ifdef OPENSSL_HAS_ECC
 	case KEY_ECDSA:
 		if (!PEM_write_EC_PUBKEY(stdout, k->ecdsa))
 			fatal("PEM_write_EC_PUBKEY failed");
 		break;
+#endif
 	default:
 		fatal("%s: unsupported key type %s", __func__, key_type(k));
 	}
@@ -549,6 +551,7 @@
 		(*k)->type = KEY_DSA;
 		(*k)->dsa = EVP_PKEY_get1_DSA(pubkey);
 		break;
+#ifdef OPENSSL_HAS_ECC
 	case EVP_PKEY_EC:
 		*k = key_new(KEY_UNSPEC);
 		(*k)->type = KEY_ECDSA;
@@ -556,6 +559,7 @@
 		(*k)->ecdsa_nid = key_ecdsa_group_to_nid(
 		    EC_KEY_get0_group((*k)->ecdsa));
 		break;
+#endif
 	default:
 		fatal("%s: unsupported pubkey type %d", __func__,
 		    EVP_PKEY_type(pubkey->type));
@@ -632,10 +636,12 @@
 			ok = PEM_write_DSAPrivateKey(stdout, k->dsa, NULL,
 			    NULL, 0, NULL, NULL);
 			break;
+#ifdef OPENSSL_HAS_ECC
 		case KEY_ECDSA:
 			ok = PEM_write_ECPrivateKey(stdout, k->ecdsa, NULL,
 			    NULL, 0, NULL, NULL);
 			break;
+#endif
 		case KEY_RSA:
 			ok = PEM_write_RSAPrivateKey(stdout, k->rsa, NULL,
 			    NULL, 0, NULL, NULL);
diff --git a/ssh.c b/ssh.c
index 51c68d7..3ade744 100644
--- a/ssh.c
+++ b/ssh.c
@@ -783,20 +783,26 @@
 		sensitive_data.nkeys = 7;
 		sensitive_data.keys = xcalloc(sensitive_data.nkeys,
 		    sizeof(Key));
+		for (i = 0; i < sensitive_data.nkeys; i++)
+			sensitive_data.keys[i] = NULL;
 
 		PRIV_START;
 		sensitive_data.keys[0] = key_load_private_type(KEY_RSA1,
 		    _PATH_HOST_KEY_FILE, "", NULL, NULL);
 		sensitive_data.keys[1] = key_load_private_cert(KEY_DSA,
 		    _PATH_HOST_DSA_KEY_FILE, "", NULL);
+#ifdef OPENSSL_HAS_ECC
 		sensitive_data.keys[2] = key_load_private_cert(KEY_ECDSA,
 		    _PATH_HOST_ECDSA_KEY_FILE, "", NULL);
+#endif
 		sensitive_data.keys[3] = key_load_private_cert(KEY_RSA,
 		    _PATH_HOST_RSA_KEY_FILE, "", NULL);
 		sensitive_data.keys[4] = key_load_private_type(KEY_DSA,
 		    _PATH_HOST_DSA_KEY_FILE, "", NULL, NULL);
+#ifdef OPENSSL_HAS_ECC
 		sensitive_data.keys[5] = key_load_private_type(KEY_ECDSA,
 		    _PATH_HOST_ECDSA_KEY_FILE, "", NULL, NULL);
+#endif
 		sensitive_data.keys[6] = key_load_private_type(KEY_RSA,
 		    _PATH_HOST_RSA_KEY_FILE, "", NULL, NULL);
 		PRIV_END;
@@ -808,14 +814,18 @@
 		    sensitive_data.keys[6] == NULL) {
 			sensitive_data.keys[1] = key_load_cert(
 			    _PATH_HOST_DSA_KEY_FILE);
+#ifdef OPENSSL_HAS_ECC
 			sensitive_data.keys[2] = key_load_cert(
 			    _PATH_HOST_ECDSA_KEY_FILE);
+#endif
 			sensitive_data.keys[3] = key_load_cert(
 			    _PATH_HOST_RSA_KEY_FILE);
 			sensitive_data.keys[4] = key_load_public(
 			    _PATH_HOST_DSA_KEY_FILE, NULL);
+#ifdef OPENSSL_HAS_ECC
 			sensitive_data.keys[5] = key_load_public(
 			    _PATH_HOST_ECDSA_KEY_FILE, NULL);
+#endif
 			sensitive_data.keys[6] = key_load_public(
 			    _PATH_HOST_RSA_KEY_FILE, NULL);
 			sensitive_data.external_keysign = 1;