- markus@cvs.openbsd.org 2014/04/29 18:01:49
     [auth.c authfd.c authfile.c bufaux.c cipher.c cipher.h hostfile.c]
     [kex.c key.c mac.c monitor.c monitor_wrap.c myproposal.h packet.c]
     [roaming_client.c ssh-agent.c ssh-keygen.c ssh-keyscan.c ssh-keysign.c]
     [ssh-pkcs11.h ssh.c sshconnect.c sshconnect2.c sshd.c]
     make compiling against OpenSSL optional (make OPENSSL=no);
     reduces algorithms to curve25519, aes-ctr, chacha, ed25519;
     allows us to explore further options; with and ok djm
diff --git a/ChangeLog b/ChangeLog
index a68a314..d6eb5b9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -36,6 +36,14 @@
      bz#1818 - don't send channel success/failre replies on channels that
      have sent a close already; analysis and patch from Simon Tatham;
      ok markus@
+   - markus@cvs.openbsd.org 2014/04/29 18:01:49
+     [auth.c authfd.c authfile.c bufaux.c cipher.c cipher.h hostfile.c]
+     [kex.c key.c mac.c monitor.c monitor_wrap.c myproposal.h packet.c]
+     [roaming_client.c ssh-agent.c ssh-keygen.c ssh-keyscan.c ssh-keysign.c]
+     [ssh-pkcs11.h ssh.c sshconnect.c sshconnect2.c sshd.c]
+     make compiling against OpenSSL optional (make OPENSSL=no);
+     reduces algorithms to curve25519, aes-ctr, chacha, ed25519;
+     allows us to explore further options; with and ok djm
 
 20140430
  - (dtucker) [defines.h] Define __GNUC_PREREQ__ macro if we don't already
diff --git a/auth.c b/auth.c
index 9a36f1d..fcb314c 100644
--- a/auth.c
+++ b/auth.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth.c,v 1.103 2013/05/19 02:42:42 djm Exp $ */
+/* $OpenBSD: auth.c,v 1.104 2014/04/29 18:01:49 markus Exp $ */
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
  *
@@ -659,6 +659,7 @@
 int
 auth_key_is_revoked(Key *key)
 {
+#ifdef WITH_OPENSSL
 	char *key_fp;
 
 	if (options.revoked_keys_file == NULL)
@@ -671,6 +672,7 @@
 	default:
 		goto revoked;
 	}
+#endif
 	debug3("%s: treating %s as a key list", __func__,
 	    options.revoked_keys_file);
 	switch (key_in_file(key, options.revoked_keys_file, 0)) {
@@ -682,6 +684,7 @@
 		error("Revoked keys file is unreadable: refusing public key "
 		    "authentication");
 		return 1;
+#ifdef WITH_OPENSSL
 	case 1:
  revoked:
 		/* Key revoked */
@@ -690,6 +693,7 @@
 		    "%s key %s ", key_type(key), key_fp);
 		free(key_fp);
 		return 1;
+#endif
 	}
 	fatal("key_in_file returned junk");
 }
diff --git a/authfd.c b/authfd.c
index cea3f97..2d5a8dd 100644
--- a/authfd.c
+++ b/authfd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: authfd.c,v 1.92 2014/01/31 16:39:19 tedu Exp $ */
+/* $OpenBSD: authfd.c,v 1.93 2014/04/29 18:01:49 markus Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -41,9 +41,6 @@
 #include <sys/un.h>
 #include <sys/socket.h>
 
-#include <openssl/evp.h>
-#include <openssl/crypto.h>
-
 #include <fcntl.h>
 #include <stdlib.h>
 #include <signal.h>
@@ -313,8 +310,10 @@
 Key *
 ssh_get_next_identity(AuthenticationConnection *auth, char **comment, int version)
 {
+#ifdef WITH_SSH1
 	int keybits;
 	u_int bits;
+#endif
 	u_char *blob;
 	u_int blen;
 	Key *key = NULL;
@@ -328,6 +327,7 @@
 	 * error if the packet is too short or contains corrupt data.
 	 */
 	switch (version) {
+#ifdef WITH_SSH1
 	case 1:
 		key = key_new(KEY_RSA1);
 		bits = buffer_get_int(&auth->identities);
@@ -339,6 +339,7 @@
 			logit("Warning: identity keysize mismatch: actual %d, announced %u",
 			    BN_num_bits(key->rsa->n), bits);
 		break;
+#endif
 	case 2:
 		blob = buffer_get_string(&auth->identities, &blen);
 		*comment = buffer_get_string(&auth->identities, NULL);
@@ -361,6 +362,7 @@
  * supported) and 1 corresponding to protocol version 1.1.
  */
 
+#ifdef WITH_SSH1
 int
 ssh_decrypt_challenge(AuthenticationConnection *auth,
     Key* key, BIGNUM *challenge,
@@ -410,6 +412,7 @@
 	buffer_free(&buffer);
 	return success;
 }
+#endif
 
 /* ask agent to sign data, returns -1 on error, 0 on success */
 int
@@ -457,6 +460,7 @@
 
 /* Encode key for a message to the agent. */
 
+#ifdef WITH_SSH1
 static void
 ssh_encode_identity_rsa1(Buffer *b, RSA *key, const char *comment)
 {
@@ -470,6 +474,7 @@
 	buffer_put_bignum(b, key->p);	/* ssh key->q, SSL key->p */
 	buffer_put_cstring(b, comment);
 }
+#endif
 
 static void
 ssh_encode_identity_ssh2(Buffer *b, Key *key, const char *comment)
@@ -493,6 +498,7 @@
 	buffer_init(&msg);
 
 	switch (key->type) {
+#ifdef WITH_SSH1
 	case KEY_RSA1:
 		type = constrained ?
 		    SSH_AGENTC_ADD_RSA_ID_CONSTRAINED :
@@ -500,6 +506,8 @@
 		buffer_put_char(&msg, type);
 		ssh_encode_identity_rsa1(&msg, key->rsa, comment);
 		break;
+#endif
+#ifdef WITH_OPENSSL
 	case KEY_RSA:
 	case KEY_RSA_CERT:
 	case KEY_RSA_CERT_V00:
@@ -508,6 +516,7 @@
 	case KEY_DSA_CERT_V00:
 	case KEY_ECDSA:
 	case KEY_ECDSA_CERT:
+#endif
 	case KEY_ED25519:
 	case KEY_ED25519_CERT:
 		type = constrained ?
@@ -552,12 +561,15 @@
 
 	buffer_init(&msg);
 
+#ifdef WITH_SSH1
 	if (key->type == KEY_RSA1) {
 		buffer_put_char(&msg, SSH_AGENTC_REMOVE_RSA_IDENTITY);
 		buffer_put_int(&msg, BN_num_bits(key->rsa->n));
 		buffer_put_bignum(&msg, key->rsa->e);
 		buffer_put_bignum(&msg, key->rsa->n);
-	} else if (key->type != KEY_UNSPEC) {
+	} else
+#endif
+	if (key->type != KEY_UNSPEC) {
 		key_to_blob(key, &blob, &blen);
 		buffer_put_char(&msg, SSH2_AGENTC_REMOVE_IDENTITY);
 		buffer_put_string(&msg, blob, blen);
diff --git a/authfile.c b/authfile.c
index 44994a8..7cb9011 100644
--- a/authfile.c
+++ b/authfile.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: authfile.c,v 1.105 2014/04/28 03:09:18 djm Exp $ */
+/* $OpenBSD: authfile.c,v 1.106 2014/04/29 18:01:49 markus Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -43,9 +43,11 @@
 #include <sys/param.h>
 #include <sys/uio.h>
 
+#ifdef WITH_OPENSSL
 #include <openssl/err.h>
 #include <openssl/evp.h>
 #include <openssl/pem.h>
+#endif
 
 /* compatibility with old or broken OpenSSL versions */
 #include "openbsd-compat/openssl-compat.h"
@@ -419,6 +421,7 @@
 	return k;
 }
 
+#ifdef WITH_SSH1
 /*
  * Serialises the authentication (private) key to a blob, encrypting it with
  * passphrase.  The identification of the blob (lowest 64 bits of n) will
@@ -508,7 +511,9 @@
 
 	return 1;
 }
+#endif
 
+#ifdef WITH_OPENSSL
 /* convert SSH v2 key in OpenSSL PEM format */
 static int
 key_private_pem_to_blob(Key *key, Buffer *blob, const char *_passphrase,
@@ -558,6 +563,7 @@
 	BIO_free(bio);
 	return success;
 }
+#endif
 
 /* Save a key blob to a file */
 static int
@@ -588,8 +594,11 @@
     int new_format_rounds)
 {
 	switch (key->type) {
+#ifdef WITH_SSH1
 	case KEY_RSA1:
 		return key_private_rsa1_to_blob(key, blob, passphrase, comment);
+#endif
+#ifdef WITH_OPENSSL
 	case KEY_DSA:
 	case KEY_ECDSA:
 	case KEY_RSA:
@@ -598,6 +607,7 @@
 			    comment, new_format_cipher, new_format_rounds);
 		}
 		return key_private_pem_to_blob(key, blob, passphrase, comment);
+#endif
 	case KEY_ED25519:
 		return key_private_to_blob2(key, blob, passphrase,
 		    comment, new_format_cipher, new_format_rounds);
@@ -627,6 +637,7 @@
 	return success;
 }
 
+#ifdef WITH_SSH1
 /*
  * Parse the public, unencrypted portion of a RSA1 key.
  */
@@ -671,6 +682,7 @@
 
 	return pub;
 }
+#endif
 
 /* Load a key from a fd into a buffer */
 int
@@ -727,6 +739,7 @@
 	return 1;
 }
 
+#ifdef WITH_SSH1
 /*
  * Loads the public part of the ssh v1 key file.  Returns NULL if an error was
  * encountered (the file does not exist or is not readable), and the key
@@ -870,7 +883,9 @@
 	key_free(prv);
 	return NULL;
 }
+#endif
 
+#ifdef WITH_OPENSSL
 static Key *
 key_parse_private_pem(Buffer *blob, int type, const char *passphrase,
     char **commentp)
@@ -964,6 +979,7 @@
 	buffer_free(&buffer);
 	return prv;
 }
+#endif
 
 int
 key_perm_ok(int fd, const char *filename)
@@ -1000,18 +1016,24 @@
 	Key *k;
 
 	switch (type) {
+#ifdef WITH_SSH1
 	case KEY_RSA1:
 		return key_parse_private_rsa1(blob, passphrase, commentp);
+#endif
+#ifdef WITH_OPENSSL
 	case KEY_DSA:
 	case KEY_ECDSA:
 	case KEY_RSA:
 		return key_parse_private_pem(blob, type, passphrase, commentp);
+#endif
 	case KEY_ED25519:
 		return key_parse_private2(blob, type, passphrase, commentp);
 	case KEY_UNSPEC:
 		if ((k = key_parse_private2(blob, type, passphrase, commentp)))
 			return k;
+#ifdef WITH_OPENSSL
 		return key_parse_private_pem(blob, type, passphrase, commentp);
+#endif
 	default:
 		error("%s: cannot parse key type %d", __func__, type);
 		break;
@@ -1061,6 +1083,7 @@
 key_parse_private(Buffer *buffer, const char *filename,
     const char *passphrase, char **commentp)
 {
+#ifdef WITH_SSH1
 	Key *pub, *prv;
 
 	/* it's a SSH v1 key if the public key part is readable */
@@ -1078,6 +1101,10 @@
 		    NULL);
 	}
 	return prv;
+#else
+	return key_parse_private_type(buffer, KEY_UNSPEC,
+	    passphrase, commentp);
+#endif
 }
 
 Key *
@@ -1162,6 +1189,7 @@
 	Key *pub;
 	char file[MAXPATHLEN];
 
+#ifdef WITH_SSH1
 	/* try rsa1 private key */
 	pub = key_load_public_type(KEY_RSA1, filename, commentp);
 	if (pub != NULL)
@@ -1172,6 +1200,7 @@
 	if (key_try_load_public(pub, filename, commentp) == 1)
 		return pub;
 	key_free(pub);
+#endif
 
 	/* try ssh2 public key */
 	pub = key_new(KEY_UNSPEC);
@@ -1211,9 +1240,11 @@
 	Key *key, *pub;
 
 	switch (type) {
+#ifdef WITH_OPENSSL
 	case KEY_RSA:
 	case KEY_DSA:
 	case KEY_ECDSA:
+#endif
 	case KEY_ED25519:
 		break;
 	default:
diff --git a/bufaux.c b/bufaux.c
index 2c8f96c..320bc2c 100644
--- a/bufaux.c
+++ b/bufaux.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: bufaux.c,v 1.58 2014/04/28 03:09:18 djm Exp $ */
+/* $OpenBSD: bufaux.c,v 1.59 2014/04/29 18:01:49 markus Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -41,8 +41,6 @@
 
 #include <sys/types.h>
 
-#include <openssl/bn.h>
-
 #include <string.h>
 #include <stdarg.h>
 #include <stdlib.h>
diff --git a/cipher-aesctr.c b/cipher-aesctr.c
new file mode 100644
index 0000000..a4cf61e
--- /dev/null
+++ b/cipher-aesctr.c
@@ -0,0 +1,78 @@
+/* $OpenBSD: cipher-aesctr.c,v 1.1 2014/04/29 15:39:33 markus Exp $ */
+/*
+ * Copyright (c) 2003 Markus Friedl <markus@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/types.h>
+#include <string.h>
+
+#include "cipher-aesctr.h"
+
+/*
+ * increment counter 'ctr',
+ * the counter is of size 'len' bytes and stored in network-byte-order.
+ * (LSB at ctr[len-1], MSB at ctr[0])
+ */
+static __inline__ void
+aesctr_inc(u8 *ctr, u32 len)
+{
+	ssize_t i;
+
+#ifndef CONSTANT_TIME_INCREMENT
+	for (i = len - 1; i >= 0; i--)
+		if (++ctr[i])	/* continue on overflow */
+			return;
+#else
+	u8 x, add = 1;
+
+	for (i = len - 1; i >= 0; i--) {
+		ctr[i] += add;
+		/* constant time for: x = ctr[i] ? 1 : 0 */
+		x = ctr[i];
+		x = (x | (x >> 4)) & 0xf;
+		x = (x | (x >> 2)) & 0x3;
+		x = (x | (x >> 1)) & 0x1;
+		add *= (x^1);
+	}
+#endif
+}
+
+void
+aesctr_keysetup(aesctr_ctx *x,const u8 *k,u32 kbits,u32 ivbits)
+{
+	x->rounds = rijndaelKeySetupEnc(x->ek, k, kbits);
+}
+
+void
+aesctr_ivsetup(aesctr_ctx *x,const u8 *iv)
+{
+	memcpy(x->ctr, iv, AES_BLOCK_SIZE);
+}
+
+void
+aesctr_encrypt_bytes(aesctr_ctx *x,const u8 *m,u8 *c,u32 bytes)
+{
+	u32 n = 0;
+	u8 buf[AES_BLOCK_SIZE];
+
+	while ((bytes--) > 0) {
+		if (n == 0) {
+			rijndaelEncrypt(x->ek, x->rounds, x->ctr, buf);
+			aesctr_inc(x->ctr, AES_BLOCK_SIZE);
+		}
+		*(c++) = *(m++) ^ buf[n];
+		n = (n + 1) % AES_BLOCK_SIZE;
+	}
+}
diff --git a/cipher-aesctr.h b/cipher-aesctr.h
new file mode 100644
index 0000000..85d55bb
--- /dev/null
+++ b/cipher-aesctr.h
@@ -0,0 +1,35 @@
+/* $OpenBSD: cipher-aesctr.h,v 1.1 2014/04/29 15:39:33 markus Exp $ */
+/*
+ * Copyright (c) 2014 Markus Friedl
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef OPENSSH_AESCTR_H
+#define OPENSSH_AESCTR_H
+
+#include "rijndael.h"
+
+#define AES_BLOCK_SIZE 16
+
+typedef struct aesctr_ctx {
+	int	rounds;				/* keylen-dependent #rounds */
+	u32	ek[4*(AES_MAXROUNDS + 1)];	/* encrypt key schedule */
+	u8	ctr[AES_BLOCK_SIZE];		/* counter */
+} aesctr_ctx;
+
+void aesctr_keysetup(aesctr_ctx *x,const u8 *k,u32 kbits,u32 ivbits);
+void aesctr_ivsetup(aesctr_ctx *x,const u8 *iv);
+void aesctr_encrypt_bytes(aesctr_ctx *x,const u8 *m,u8 *c,u32 bytes);
+
+#endif
diff --git a/cipher.c b/cipher.c
index 53d9b4f..0ea073f 100644
--- a/cipher.c
+++ b/cipher.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cipher.c,v 1.97 2014/02/07 06:55:54 djm Exp $ */
+/* $OpenBSD: cipher.c,v 1.98 2014/04/29 18:01:49 markus Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -53,9 +53,11 @@
 /* compatibility with old or broken OpenSSL versions */
 #include "openbsd-compat/openssl-compat.h"
 
+#ifdef WITH_SSH1
 extern const EVP_CIPHER *evp_ssh1_bf(void);
 extern const EVP_CIPHER *evp_ssh1_3des(void);
 extern void ssh1_3des_iv(EVP_CIPHER_CTX *, int, u_char *, int);
+#endif
 
 struct Cipher {
 	char	*name;
@@ -68,15 +70,23 @@
 	u_int	flags;
 #define CFLAG_CBC		(1<<0)
 #define CFLAG_CHACHAPOLY	(1<<1)
+#define CFLAG_AESCTR		(1<<2)
+#define CFLAG_NONE		(1<<3)
+#ifdef WITH_OPENSSL
 	const EVP_CIPHER	*(*evptype)(void);
+#else
+	void	*ignored;
+#endif
 };
 
 static const struct Cipher ciphers[] = {
-	{ "none",	SSH_CIPHER_NONE, 8, 0, 0, 0, 0, 0, EVP_enc_null },
+#ifdef WITH_SSH1
 	{ "des",	SSH_CIPHER_DES, 8, 8, 0, 0, 0, 1, EVP_des_cbc },
 	{ "3des",	SSH_CIPHER_3DES, 8, 16, 0, 0, 0, 1, evp_ssh1_3des },
 	{ "blowfish",	SSH_CIPHER_BLOWFISH, 8, 32, 0, 0, 0, 1, evp_ssh1_bf },
-
+#endif
+#ifdef WITH_OPENSSL
+	{ "none",	SSH_CIPHER_NONE, 8, 0, 0, 0, 0, 0, EVP_enc_null },
 	{ "3des-cbc",	SSH_CIPHER_SSH2, 8, 24, 0, 0, 0, 1, EVP_des_ede3_cbc },
 	{ "blowfish-cbc",
 			SSH_CIPHER_SSH2, 8, 16, 0, 0, 0, 1, EVP_bf_cbc },
@@ -99,6 +109,12 @@
 	{ "aes256-gcm@openssh.com",
 			SSH_CIPHER_SSH2, 16, 32, 12, 16, 0, 0, EVP_aes_256_gcm },
 #endif
+#else /* WITH_OPENSSL */
+	{ "aes128-ctr",	SSH_CIPHER_SSH2, 16, 16, 0, 0, 0, CFLAG_AESCTR, NULL },
+	{ "aes192-ctr",	SSH_CIPHER_SSH2, 16, 24, 0, 0, 0, CFLAG_AESCTR, NULL },
+	{ "aes256-ctr",	SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, CFLAG_AESCTR, NULL },
+	{ "none",	SSH_CIPHER_NONE, 8, 0, 0, 0, 0, CFLAG_NONE, NULL },
+#endif /* WITH_OPENSSL */
 	{ "chacha20-poly1305@openssh.com",
 			SSH_CIPHER_SSH2, 8, 64, 0, 16, 0, CFLAG_CHACHAPOLY, NULL },
 	{ NULL,		SSH_CIPHER_INVALID, 0, 0, 0, 0, 0, 0, NULL }
@@ -264,6 +280,7 @@
     const u_char *key, u_int keylen, const u_char *iv, u_int ivlen,
     int do_encrypt)
 {
+#ifdef WITH_OPENSSL
 	static int dowarn = 1;
 #ifdef SSH_OLD_EVP
 	EVP_CIPHER *type;
@@ -282,6 +299,7 @@
 		if (keylen > 8)
 			keylen = 8;
 	}
+#endif
 	cc->plaintext = (cipher->number == SSH_CIPHER_NONE);
 	cc->encrypt = do_encrypt;
 
@@ -297,6 +315,16 @@
 		chachapoly_init(&cc->cp_ctx, key, keylen);
 		return;
 	}
+#ifndef WITH_OPENSSL
+	if ((cc->cipher->flags & CFLAG_AESCTR) != 0) {
+		aesctr_keysetup(&cc->ac_ctx, key, 8 * keylen, 8 * ivlen);
+		aesctr_ivsetup(&cc->ac_ctx, iv);
+		return;
+	}
+	if ((cc->cipher->flags & CFLAG_NONE) != 0)
+		return;
+	fatal("unsupported cipher");
+#else
 	type = (*cipher->evptype)();
 	EVP_CIPHER_CTX_init(&cc->evp);
 #ifdef SSH_OLD_EVP
@@ -339,6 +367,7 @@
 		free(junk);
 		free(discard);
 	}
+#endif
 }
 
 /*
@@ -360,6 +389,20 @@
 	if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0)
 		return chachapoly_crypt(&cc->cp_ctx, seqnr, dest, src, len,
 		    aadlen, authlen, cc->encrypt);
+#ifndef WITH_OPENSSL
+	if ((cc->cipher->flags & CFLAG_AESCTR) != 0) {
+		if (aadlen)
+			memcpy(dest, src, aadlen);
+		aesctr_encrypt_bytes(&cc->ac_ctx, src + aadlen,
+		    dest + aadlen, len);
+		return 0;
+	}
+	if ((cc->cipher->flags & CFLAG_NONE) != 0) {
+		memcpy(dest, src, aadlen + len);
+		return 0;
+	}
+	fatal("unsupported cipher");
+#else
 	if (authlen) {
 		u_char lastiv[1];
 
@@ -400,6 +443,7 @@
 			fatal("%s: EVP_CTRL_GCM_GET_TAG", __func__);
 	}
 	return 0;
+#endif
 }
 
 /* Extract the packet length, including any decryption necessary beforehand */
@@ -421,8 +465,12 @@
 {
 	if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0)
 		explicit_bzero(&cc->cp_ctx, sizeof(cc->cp_ctx));
+	else if ((cc->cipher->flags & CFLAG_AESCTR) != 0)
+		explicit_bzero(&cc->ac_ctx, sizeof(cc->ac_ctx));
+#ifdef WITH_OPENSSL
 	else if (EVP_CIPHER_CTX_cleanup(&cc->evp) == 0)
 		error("cipher_cleanup: EVP_CIPHER_CTX_cleanup failed");
+#endif
 }
 
 /*
@@ -455,14 +503,16 @@
 cipher_get_keyiv_len(const CipherContext *cc)
 {
 	const Cipher *c = cc->cipher;
-	int ivlen;
+	int ivlen = 0;
 
 	if (c->number == SSH_CIPHER_3DES)
 		ivlen = 24;
 	else if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0)
 		ivlen = 0;
+#ifdef WITH_OPENSSL
 	else
 		ivlen = EVP_CIPHER_CTX_iv_length(&cc->evp);
+#endif
 	return (ivlen);
 }
 
@@ -470,15 +520,20 @@
 cipher_get_keyiv(CipherContext *cc, u_char *iv, u_int len)
 {
 	const Cipher *c = cc->cipher;
+#ifdef WITH_OPENSSL
 	int evplen;
+#endif
 
 	if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) {
 		if (len != 0)
 			fatal("%s: wrong iv length %d != %d", __func__, len, 0);
 		return;
 	}
+	if ((cc->cipher->flags & CFLAG_NONE) != 0)
+		return;
 
 	switch (c->number) {
+#ifdef WITH_OPENSSL
 	case SSH_CIPHER_SSH2:
 	case SSH_CIPHER_DES:
 	case SSH_CIPHER_BLOWFISH:
@@ -492,17 +547,20 @@
 		if (c->evptype == evp_rijndael)
 			ssh_rijndael_iv(&cc->evp, 0, iv, len);
 		else
-#endif
+#endif /* USE_BUILTIN_RIJNDAEL */
 #ifndef OPENSSL_HAVE_EVPCTR
 		if (c->evptype == evp_aes_128_ctr)
 			ssh_aes_ctr_iv(&cc->evp, 0, iv, len);
 		else
-#endif
+#endif /* OPENSSL_HAVE_EVPCTR */
 		memcpy(iv, cc->evp.iv, len);
 		break;
+#endif /* WITH_OPENSSL */
+#ifdef WITH_SSH1
 	case SSH_CIPHER_3DES:
 		ssh1_3des_iv(&cc->evp, 0, iv, 24);
 		break;
+#endif /* WITH_SSH1 */
 	default:
 		fatal("%s: bad cipher %d", __func__, c->number);
 	}
@@ -512,12 +570,17 @@
 cipher_set_keyiv(CipherContext *cc, u_char *iv)
 {
 	const Cipher *c = cc->cipher;
+#ifdef WITH_OPENSSL
 	int evplen = 0;
+#endif
 
 	if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0)
 		return;
+	if ((cc->cipher->flags & CFLAG_NONE) != 0)
+		return;
 
 	switch (c->number) {
+#ifdef WITH_OPENSSL
 	case SSH_CIPHER_SSH2:
 	case SSH_CIPHER_DES:
 	case SSH_CIPHER_BLOWFISH:
@@ -528,17 +591,20 @@
 		if (c->evptype == evp_rijndael)
 			ssh_rijndael_iv(&cc->evp, 1, iv, evplen);
 		else
-#endif
+#endif /* USE_BUILTIN_RIJNDAEL */
 #ifndef OPENSSL_HAVE_EVPCTR
 		if (c->evptype == evp_aes_128_ctr)
 			ssh_aes_ctr_iv(&cc->evp, 1, iv, evplen);
 		else
-#endif
+#endif /* OPENSSL_HAVE_EVPCTR */
 		memcpy(cc->evp.iv, iv, evplen);
 		break;
+#endif /* WITH_OPENSSL */
+#ifdef WITH_SSH1
 	case SSH_CIPHER_3DES:
 		ssh1_3des_iv(&cc->evp, 1, iv, 24);
 		break;
+#endif /* WITH_SSH1 */
 	default:
 		fatal("%s: bad cipher %d", __func__, c->number);
 	}
@@ -547,6 +613,7 @@
 int
 cipher_get_keycontext(const CipherContext *cc, u_char *dat)
 {
+#ifdef WITH_OPENSSL
 	const Cipher *c = cc->cipher;
 	int plen = 0;
 
@@ -557,11 +624,15 @@
 		memcpy(dat, EVP_X_STATE(cc->evp), plen);
 	}
 	return (plen);
+#else
+	return (0);
+#endif
 }
 
 void
 cipher_set_keycontext(CipherContext *cc, u_char *dat)
 {
+#ifdef WITH_OPENSSL
 	const Cipher *c = cc->cipher;
 	int plen;
 
@@ -569,4 +640,5 @@
 		plen = EVP_X_STATE_LEN(cc->evp);
 		memcpy(EVP_X_STATE(cc->evp), dat, plen);
 	}
+#endif
 }
diff --git a/cipher.h b/cipher.h
index 133d2e7..5aa778f 100644
--- a/cipher.h
+++ b/cipher.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: cipher.h,v 1.44 2014/01/25 10:12:50 dtucker Exp $ */
+/* $OpenBSD: cipher.h,v 1.45 2014/04/29 18:01:49 markus Exp $ */
 
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -39,6 +39,7 @@
 
 #include <openssl/evp.h>
 #include "cipher-chachapoly.h"
+#include "cipher-aesctr.h"
 
 /*
  * Cipher types for SSH-1.  New types can be added, but old types should not
@@ -69,6 +70,7 @@
 	int	encrypt;
 	EVP_CIPHER_CTX evp;
 	struct chachapoly_ctx cp_ctx; /* XXX union with evp? */
+	struct aesctr_ctx ac_ctx; /* XXX union with evp? */
 	const Cipher *cipher;
 };
 
diff --git a/hostfile.c b/hostfile.c
index 8bc9540..91741ca 100644
--- a/hostfile.c
+++ b/hostfile.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: hostfile.c,v 1.55 2014/01/31 16:39:19 tedu Exp $ */
+/* $OpenBSD: hostfile.c,v 1.56 2014/04/29 18:01:49 markus Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -182,6 +182,7 @@
 hostfile_check_key(int bits, const Key *key, const char *host,
     const char *filename, u_long linenum)
 {
+#ifdef WITH_SSH1
 	if (key == NULL || key->type != KEY_RSA1 || key->rsa == NULL)
 		return 1;
 	if (bits != BN_num_bits(key->rsa->n)) {
@@ -191,6 +192,7 @@
 		logit("Warning: replace %d with %d in %s, line %lu.",
 		    bits, BN_num_bits(key->rsa->n), filename, linenum);
 	}
+#endif
 	return 1;
 }
 
@@ -296,11 +298,15 @@
 		key = key_new(KEY_UNSPEC);
 		if (!hostfile_read_key(&cp, &kbits, key)) {
 			key_free(key);
+#ifdef WITH_SSH1
 			key = key_new(KEY_RSA1);
 			if (!hostfile_read_key(&cp, &kbits, key)) {
 				key_free(key);
 				continue;
 			}
+#else
+			continue;
+#endif
 		}
 		if (!hostfile_check_key(kbits, key, host, path, linenum))
 			continue;
diff --git a/kex.c b/kex.c
index 74e2b86..a173e70 100644
--- a/kex.c
+++ b/kex.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kex.c,v 1.98 2014/02/02 03:44:31 djm Exp $ */
+/* $OpenBSD: kex.c,v 1.99 2014/04/29 18:01:49 markus Exp $ */
 /*
  * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
  *
@@ -33,7 +33,9 @@
 #include <stdlib.h>
 #include <string.h>
 
+#ifdef WITH_OPENSSL
 #include <openssl/crypto.h>
+#endif
 
 #include "xmalloc.h"
 #include "ssh2.h"
@@ -70,12 +72,13 @@
 	int hash_alg;
 };
 static const struct kexalg kexalgs[] = {
+#ifdef WITH_OPENSSL
 	{ KEX_DH1, KEX_DH_GRP1_SHA1, 0, SSH_DIGEST_SHA1 },
 	{ KEX_DH14, KEX_DH_GRP14_SHA1, 0, SSH_DIGEST_SHA1 },
 	{ KEX_DHGEX_SHA1, KEX_DH_GEX_SHA1, 0, SSH_DIGEST_SHA1 },
 #ifdef HAVE_EVP_SHA256
 	{ KEX_DHGEX_SHA256, KEX_DH_GEX_SHA256, 0, SSH_DIGEST_SHA256 },
-#endif
+#endif /* HAVE_EVP_SHA256 */
 #ifdef OPENSSL_HAS_ECC
 	{ KEX_ECDH_SHA2_NISTP256, KEX_ECDH_SHA2,
 	    NID_X9_62_prime256v1, SSH_DIGEST_SHA256 },
@@ -84,12 +87,13 @@
 # ifdef OPENSSL_HAS_NISTP521
 	{ KEX_ECDH_SHA2_NISTP521, KEX_ECDH_SHA2, NID_secp521r1,
 	    SSH_DIGEST_SHA512 },
-# endif
-#endif
+# endif /* OPENSSL_HAS_NISTP521 */
+#endif /* OPENSSL_HAS_ECC */
 	{ KEX_DH1, KEX_DH_GRP1_SHA1, 0, SSH_DIGEST_SHA1 },
+#endif /* WITH_OPENSSL */
 #ifdef HAVE_EVP_SHA256
 	{ KEX_CURVE25519_SHA256, KEX_C25519_SHA256, 0, SSH_DIGEST_SHA256 },
-#endif
+#endif /* HAVE_EVP_SHA256 */
 	{ NULL, -1, -1, -1},
 };
 
@@ -615,6 +619,7 @@
 	}
 }
 
+#ifdef WITH_OPENSSL
 void
 kex_derive_keys_bn(Kex *kex, u_char *hash, u_int hashlen, const BIGNUM *secret)
 {
@@ -626,6 +631,7 @@
 	    buffer_ptr(&shared_secret), buffer_len(&shared_secret));
 	buffer_free(&shared_secret);
 }
+#endif
 
 Newkeys *
 kex_get_newkeys(int mode)
@@ -637,6 +643,7 @@
 	return ret;
 }
 
+#ifdef WITH_SSH1
 void
 derive_ssh1_session_id(BIGNUM *host_modulus, BIGNUM *server_modulus,
     u_int8_t cookie[8], u_int8_t id[16])
@@ -669,6 +676,7 @@
 	explicit_bzero(nbuf, sizeof(nbuf));
 	explicit_bzero(obuf, sizeof(obuf));
 }
+#endif
 
 #if defined(DEBUG_KEX) || defined(DEBUG_KEXDH) || defined(DEBUG_KEXECDH)
 void
diff --git a/key.c b/key.c
index 168e1b7..e8fc5b1 100644
--- a/key.c
+++ b/key.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: key.c,v 1.116 2014/02/02 03:44:31 djm Exp $ */
+/* $OpenBSD: key.c,v 1.117 2014/04/29 18:01:49 markus Exp $ */
 /*
  * read_bignum():
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -80,8 +80,11 @@
 key_new(int type)
 {
 	Key *k;
+#ifdef WITH_OPENSSL
 	RSA *rsa;
 	DSA *dsa;
+#endif
+
 	k = xcalloc(1, sizeof(*k));
 	k->type = type;
 	k->ecdsa = NULL;
@@ -92,6 +95,7 @@
 	k->ed25519_sk = NULL;
 	k->ed25519_pk = NULL;
 	switch (k->type) {
+#ifdef WITH_OPENSSL
 	case KEY_RSA1:
 	case KEY_RSA:
 	case KEY_RSA_CERT_V00:
@@ -125,6 +129,7 @@
 		/* Cannot do anything until we know the group */
 		break;
 #endif
+#endif
 	case KEY_ED25519:
 	case KEY_ED25519_CERT:
 		/* no need to prealloc */
@@ -146,6 +151,7 @@
 key_add_private(Key *k)
 {
 	switch (k->type) {
+#ifdef WITH_OPENSSL
 	case KEY_RSA1:
 	case KEY_RSA:
 	case KEY_RSA_CERT_V00:
@@ -173,6 +179,7 @@
 	case KEY_ECDSA_CERT:
 		/* Cannot do anything until we know the group */
 		break;
+#endif
 	case KEY_ED25519:
 	case KEY_ED25519_CERT:
 		/* no need to prealloc */
@@ -216,6 +223,7 @@
 	if (k == NULL)
 		fatal("key_free: key is NULL");
 	switch (k->type) {
+#ifdef WITH_OPENSSL
 	case KEY_RSA1:
 	case KEY_RSA:
 	case KEY_RSA_CERT_V00:
@@ -289,7 +297,7 @@
 int
 key_equal_public(const Key *a, const Key *b)
 {
-#ifdef OPENSSL_HAS_ECC
+#if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC)
 	BN_CTX *bnctx;
 #endif
 
@@ -298,6 +306,7 @@
 		return 0;
 
 	switch (a->type) {
+#ifdef WITH_OPENSSL
 	case KEY_RSA1:
 	case KEY_RSA_CERT_V00:
 	case KEY_RSA_CERT:
@@ -333,6 +342,7 @@
 		BN_CTX_free(bnctx);
 		return 1;
 #endif /* OPENSSL_HAS_ECC */
+#endif /* WITH_OPENSSL */
 	case KEY_ED25519:
 	case KEY_ED25519_CERT:
 		return a->ed25519_pk != NULL && b->ed25519_pk != NULL &&
@@ -362,7 +372,10 @@
 	u_char *blob = NULL;
 	u_char *retval = NULL;
 	u_int len = 0;
-	int nlen, elen, hash_alg = -1;
+	int hash_alg = -1;
+#ifdef WITH_OPENSSL
+	int nlen, elen;
+#endif
 
 	*dgst_raw_length = 0;
 
@@ -381,6 +394,7 @@
 		fatal("%s: bad digest type %d", __func__, dgst_type);
 	}
 	switch (k->type) {
+#ifdef WITH_OPENSSL
 	case KEY_RSA1:
 		nlen = BN_num_bytes(k->rsa->n);
 		elen = BN_num_bytes(k->rsa->e);
@@ -392,14 +406,17 @@
 	case KEY_DSA:
 	case KEY_ECDSA:
 	case KEY_RSA:
+#endif
 	case KEY_ED25519:
 		key_to_blob(k, &blob, &len);
 		break;
+#ifdef WITH_OPENSSL
 	case KEY_DSA_CERT_V00:
 	case KEY_RSA_CERT_V00:
 	case KEY_DSA_CERT:
 	case KEY_ECDSA_CERT:
 	case KEY_RSA_CERT:
+#endif
 	case KEY_ED25519_CERT:
 		/* We want a fingerprint of the _key_ not of the cert */
 		to_blob(k, &blob, &len, 1);
@@ -628,6 +645,7 @@
 	return retval;
 }
 
+#ifdef WITH_SSH1
 /*
  * Reads a multiple-precision integer in decimal from the buffer, and advances
  * the pointer.  The integer must already be initialized.  This function is
@@ -684,6 +702,7 @@
 	OPENSSL_free(buf);
 	return 1;
 }
+#endif
 
 /* returns 1 ok, -1 error */
 int
@@ -693,8 +712,10 @@
 	int success = -1;
 	char *cp, *space;
 	int len, n, type;
-	u_int bits;
 	u_char *blob;
+#ifdef WITH_SSH1
+	u_int bits;
+#endif
 #ifdef OPENSSL_HAS_ECC
 	int curve_nid = -1;
 #endif
@@ -703,6 +724,7 @@
 
 	switch (ret->type) {
 	case KEY_RSA1:
+#ifdef WITH_SSH1
 		/* Get number of bits. */
 		if (*cp < '0' || *cp > '9')
 			return -1;	/* Bad bit count... */
@@ -723,6 +745,7 @@
 			return -1;
 		}
 		success = 1;
+#endif
 		break;
 	case KEY_UNSPEC:
 	case KEY_RSA:
@@ -805,6 +828,7 @@
 			ret->cert = k->cert;
 			k->cert = NULL;
 		}
+#ifdef WITH_OPENSSL
 		if (key_type_plain(ret->type) == KEY_RSA) {
 			if (ret->rsa != NULL)
 				RSA_free(ret->rsa);
@@ -836,6 +860,7 @@
 #endif
 		}
 #endif
+#endif
 		if (key_type_plain(ret->type) == KEY_ED25519) {
 			free(ret->ed25519_pk);
 			ret->ed25519_pk = k->ed25519_pk;
@@ -867,7 +892,10 @@
 key_write(const Key *key, FILE *f)
 {
 	int n, success = 0;
-	u_int len, bits = 0;
+#ifdef WITH_SSH1
+	u_int bits = 0;
+#endif
+	u_int len;
 	u_char *blob;
 	char *uu;
 
@@ -883,6 +911,7 @@
 	}
 
 	switch (key->type) {
+#ifdef WITH_SSH1
 	case KEY_RSA1:
 		if (key->rsa == NULL)
 			return 0;
@@ -894,6 +923,8 @@
 			return 1;
 		error("key_write: failed for RSA key");
 		return 0;
+#endif
+#ifdef WITH_OPENSSL
 	case KEY_DSA:
 	case KEY_DSA_CERT_V00:
 	case KEY_DSA_CERT:
@@ -907,17 +938,18 @@
 			return 0;
 		break;
 #endif
-	case KEY_ED25519:
-	case KEY_ED25519_CERT:
-		if (key->ed25519_pk == NULL)
-			return 0;
-		break;
 	case KEY_RSA:
 	case KEY_RSA_CERT_V00:
 	case KEY_RSA_CERT:
 		if (key->rsa == NULL)
 			return 0;
 		break;
+#endif
+	case KEY_ED25519:
+	case KEY_ED25519_CERT:
+		if (key->ed25519_pk == NULL)
+			return 0;
+		break;
 	default:
 		return 0;
 	}
@@ -956,10 +988,12 @@
 	int cert;
 };
 static const struct keytype keytypes[] = {
+#ifdef WITH_OPENSSL
+#ifdef WITH_SSH1
 	{ NULL, "RSA1", KEY_RSA1, 0, 0 },
+#endif
 	{ "ssh-rsa", "RSA", KEY_RSA, 0, 0 },
 	{ "ssh-dss", "DSA", KEY_DSA, 0, 0 },
-	{ "ssh-ed25519", "ED25519", KEY_ED25519, 0, 0 },
 #ifdef OPENSSL_HAS_ECC
 	{ "ecdsa-sha2-nistp256", "ECDSA", KEY_ECDSA, NID_X9_62_prime256v1, 0 },
 	{ "ecdsa-sha2-nistp384", "ECDSA", KEY_ECDSA, NID_secp384r1, 0 },
@@ -983,6 +1017,8 @@
 	    KEY_RSA_CERT_V00, 0, 1 },
 	{ "ssh-dss-cert-v00@openssh.com", "DSA-CERT-V00",
 	    KEY_DSA_CERT_V00, 0, 1 },
+#endif
+	{ "ssh-ed25519", "ED25519", KEY_ED25519, 0, 0 },
 	{ "ssh-ed25519-cert-v01@openssh.com", "ED25519-CERT",
 	    KEY_ED25519_CERT, 0, 1 },
 	{ NULL, NULL, -1, -1, 0 }
@@ -1107,6 +1143,7 @@
 key_size(const Key *k)
 {
 	switch (k->type) {
+#ifdef WITH_OPENSSL
 	case KEY_RSA1:
 	case KEY_RSA:
 	case KEY_RSA_CERT_V00:
@@ -1116,17 +1153,19 @@
 	case KEY_DSA_CERT_V00:
 	case KEY_DSA_CERT:
 		return BN_num_bits(k->dsa->p);
-	case KEY_ED25519:
-		return 256;	/* XXX */
 #ifdef OPENSSL_HAS_ECC
 	case KEY_ECDSA:
 	case KEY_ECDSA_CERT:
 		return key_curve_nid_to_bits(k->ecdsa_nid);
 #endif
+#endif
+	case KEY_ED25519:
+		return 256;	/* XXX */
 	}
 	return 0;
 }
 
+#ifdef WITH_OPENSSL
 static RSA *
 rsa_generate_private_key(u_int bits)
 {
@@ -1243,12 +1282,14 @@
 	return private;
 }
 #endif /* OPENSSL_HAS_ECC */
+#endif /* WITH_OPENSSL */
 
 Key *
 key_generate(int type, u_int bits)
 {
 	Key *k = key_new(KEY_UNSPEC);
 	switch (type) {
+#ifdef WITH_OPENSSL
 	case KEY_DSA:
 		k->dsa = dsa_generate_private_key(bits);
 		break;
@@ -1261,16 +1302,18 @@
 	case KEY_RSA1:
 		k->rsa = rsa_generate_private_key(bits);
 		break;
-	case KEY_ED25519:
-		k->ed25519_pk = xmalloc(ED25519_PK_SZ);
-		k->ed25519_sk = xmalloc(ED25519_SK_SZ);
-		crypto_sign_ed25519_keypair(k->ed25519_pk, k->ed25519_sk);
-		break;
+#endif
 	case KEY_RSA_CERT_V00:
 	case KEY_DSA_CERT_V00:
 	case KEY_RSA_CERT:
 	case KEY_DSA_CERT:
 		fatal("key_generate: cert keys cannot be generated directly");
+#endif
+	case KEY_ED25519:
+		k->ed25519_pk = xmalloc(ED25519_PK_SZ);
+		k->ed25519_sk = xmalloc(ED25519_SK_SZ);
+		crypto_sign_ed25519_keypair(k->ed25519_pk, k->ed25519_sk);
+		break;
 	default:
 		fatal("key_generate: unknown type %d", type);
 	}
@@ -1328,6 +1371,7 @@
 {
 	Key *n = NULL;
 	switch (k->type) {
+#ifdef WITH_OPENSSL
 	case KEY_DSA:
 	case KEY_DSA_CERT_V00:
 	case KEY_DSA_CERT:
@@ -1359,6 +1403,7 @@
 		    (BN_copy(n->rsa->e, k->rsa->e) == NULL))
 			fatal("key_from_private: BN_copy failed");
 		break;
+#endif
 	case KEY_ED25519:
 	case KEY_ED25519_CERT:
 		n = key_new(k->type);
@@ -1556,6 +1601,7 @@
 		goto out;
 	}
 	switch (type) {
+#ifdef WITH_OPENSSL
 	case KEY_RSA_CERT:
 		(void)buffer_get_string_ptr_ret(&b, NULL); /* Skip nonce */
 		/* FALLTHROUGH */
@@ -1565,10 +1611,7 @@
 		if (buffer_get_bignum2_ret(&b, key->rsa->e) == -1 ||
 		    buffer_get_bignum2_ret(&b, key->rsa->n) == -1) {
 			error("key_from_blob: can't read rsa key");
- badkey:
-			key_free(key);
-			key = NULL;
-			goto out;
+			goto badkey;
 		}
 #ifdef DEBUG_PK
 		RSA_print_fp(stderr, key->rsa, 8);
@@ -1669,6 +1712,11 @@
 #endif
 	buffer_free(&b);
 	return key;
+
+ badkey:
+	key_free(key);
+	key = NULL;
+	goto out;
 }
 
 Key *
@@ -1694,16 +1742,19 @@
 	buffer_init(&b);
 	type = force_plain ? key_type_plain(key->type) : key->type;
 	switch (type) {
+#ifdef WITH_OPENSSL
 	case KEY_DSA_CERT_V00:
 	case KEY_RSA_CERT_V00:
 	case KEY_DSA_CERT:
 	case KEY_ECDSA_CERT:
 	case KEY_RSA_CERT:
+#endif
 	case KEY_ED25519_CERT:
 		/* Use the existing blob */
 		buffer_append(&b, buffer_ptr(&key->cert->certblob),
 		    buffer_len(&key->cert->certblob));
 		break;
+#ifdef WITH_OPENSSL
 	case KEY_DSA:
 		buffer_put_cstring(&b,
 		    key_ssh_name_from_type_nid(type, key->ecdsa_nid));
@@ -1727,6 +1778,7 @@
 		buffer_put_bignum2(&b, key->rsa->e);
 		buffer_put_bignum2(&b, key->rsa->n);
 		break;
+#endif
 	case KEY_ED25519:
 		buffer_put_cstring(&b,
 		    key_ssh_name_from_type_nid(type, key->ecdsa_nid));
@@ -1762,6 +1814,7 @@
     const u_char *data, u_int datalen)
 {
 	switch (key->type) {
+#ifdef WITH_OPENSSL
 	case KEY_DSA_CERT_V00:
 	case KEY_DSA_CERT:
 	case KEY_DSA:
@@ -1775,6 +1828,7 @@
 	case KEY_RSA_CERT:
 	case KEY_RSA:
 		return ssh_rsa_sign(key, sigp, lenp, data, datalen);
+#endif
 	case KEY_ED25519:
 	case KEY_ED25519_CERT:
 		return ssh_ed25519_sign(key, sigp, lenp, data, datalen);
@@ -1798,6 +1852,7 @@
 		return -1;
 
 	switch (key->type) {
+#ifdef WITH_OPENSSL
 	case KEY_DSA_CERT_V00:
 	case KEY_DSA_CERT:
 	case KEY_DSA:
@@ -1811,6 +1866,7 @@
 	case KEY_RSA_CERT:
 	case KEY_RSA:
 		return ssh_rsa_verify(key, signature, signaturelen, data, datalen);
+#endif
 	case KEY_ED25519:
 	case KEY_ED25519_CERT:
 		return ssh_ed25519_verify(key, signature, signaturelen, data, datalen);
@@ -1837,6 +1893,7 @@
 	pk->ed25519_sk = NULL;
 
 	switch (k->type) {
+#ifdef WITH_OPENSSL
 	case KEY_RSA_CERT_V00:
 	case KEY_RSA_CERT:
 		key_cert_copy(k, pk);
@@ -2007,6 +2064,7 @@
 
 	/* XXX this substantially duplicates to_blob(); refactor */
 	switch (k->type) {
+#ifdef WITH_OPENSSL
 	case KEY_DSA_CERT_V00:
 	case KEY_DSA_CERT:
 		buffer_put_bignum2(&k->cert->certblob, k->dsa->p);
@@ -2028,6 +2086,7 @@
 		buffer_put_bignum2(&k->cert->certblob, k->rsa->e);
 		buffer_put_bignum2(&k->cert->certblob, k->rsa->n);
 		break;
+#endif
 	case KEY_ED25519_CERT:
 		buffer_put_string(&k->cert->certblob,
 		    k->ed25519_pk, ED25519_PK_SZ);
@@ -2152,6 +2211,7 @@
 	}
 }
 
+#ifdef WITH_OPENSSL
 /* XXX: these are really begging for a table-driven approach */
 int
 key_curve_name_to_nid(const char *name)
@@ -2349,6 +2409,7 @@
 	BN_CTX_free(bnctx);
 	return ret;
 }
+#endif
 
 #if defined(DEBUG_KEXECDH) || defined(DEBUG_PK)
 void
@@ -2400,6 +2461,7 @@
 {
 	buffer_put_cstring(b, key_ssh_name(key));
 	switch (key->type) {
+#ifdef WITH_OPENSSL
 	case KEY_RSA:
 		buffer_put_bignum2(b, key->rsa->n);
 		buffer_put_bignum2(b, key->rsa->e);
@@ -2453,6 +2515,8 @@
 		buffer_put_string(b, key->ed25519_pk, ED25519_PK_SZ);
 		buffer_put_string(b, key->ed25519_sk, ED25519_SK_SZ);
 		break;
+#endif
+#endif
 	case KEY_ED25519_CERT:
 		if (key->cert == NULL || buffer_len(&key->cert->certblob) == 0)
 			fatal("%s: no cert/certblob", __func__);
@@ -2472,7 +2536,7 @@
 	u_char *cert;
 	u_int len, pklen, sklen;
 	int type;
-#ifdef OPENSSL_HAS_ECC
+#if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC)
 	char *curve;
 	BIGNUM *exponent;
 	EC_POINT *q;
@@ -2481,6 +2545,7 @@
 	type_name = buffer_get_string(blob, NULL);
 	type = key_type_from_name(type_name);
 	switch (type) {
+#ifdef WITH_OPENSSL
 	case KEY_DSA:
 		k = key_new_private(type);
 		buffer_get_bignum2(blob, k->dsa->p);
@@ -2575,6 +2640,8 @@
 		buffer_get_bignum2(blob, k->rsa->p);
 		buffer_get_bignum2(blob, k->rsa->q);
 		break;
+#endif
+#endif
 	case KEY_ED25519:
 		k = key_new_private(type);
 		k->ed25519_pk = buffer_get_string(blob, &pklen);
@@ -2610,6 +2677,7 @@
 
 	/* enable blinding */
 	switch (k->type) {
+#ifdef WITH_OPENSSL
 	case KEY_RSA:
 	case KEY_RSA_CERT_V00:
 	case KEY_RSA_CERT:
@@ -2620,6 +2688,7 @@
 			return NULL;
 		}
 		break;
+#endif
 	}
 	return k;
 }
diff --git a/mac.c b/mac.c
index 0977572..fc2bd42 100644
--- a/mac.c
+++ b/mac.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mac.c,v 1.28 2014/02/07 06:55:54 djm Exp $ */
+/* $OpenBSD: mac.c,v 1.29 2014/04/29 18:01:49 markus Exp $ */
 /*
  * Copyright (c) 2001 Markus Friedl.  All rights reserved.
  *
@@ -72,8 +72,10 @@
 	{ "hmac-md5-96",			SSH_DIGEST, SSH_DIGEST_MD5, 96, 0, 0, 0 },
 	{ "hmac-ripemd160",			SSH_DIGEST, SSH_DIGEST_RIPEMD160, 0, 0, 0, 0 },
 	{ "hmac-ripemd160@openssh.com",		SSH_DIGEST, SSH_DIGEST_RIPEMD160, 0, 0, 0, 0 },
+#ifdef WITH_OPENSSL
 	{ "umac-64@openssh.com",		SSH_UMAC, 0, 0, 128, 64, 0 },
 	{ "umac-128@openssh.com",		SSH_UMAC128, 0, 0, 128, 128, 0 },
+#endif
 
 	/* Encrypt-then-MAC variants */
 	{ "hmac-sha1-etm@openssh.com",		SSH_DIGEST, SSH_DIGEST_SHA1, 0, 0, 0, 1 },
@@ -85,8 +87,10 @@
 	{ "hmac-md5-etm@openssh.com",		SSH_DIGEST, SSH_DIGEST_MD5, 0, 0, 0, 1 },
 	{ "hmac-md5-96-etm@openssh.com",	SSH_DIGEST, SSH_DIGEST_MD5, 96, 0, 0, 1 },
 	{ "hmac-ripemd160-etm@openssh.com",	SSH_DIGEST, SSH_DIGEST_RIPEMD160, 0, 0, 0, 1 },
+#ifdef WITH_OPENSSL
 	{ "umac-64-etm@openssh.com",		SSH_UMAC, 0, 0, 128, 64, 1 },
 	{ "umac-128-etm@openssh.com",		SSH_UMAC128, 0, 0, 128, 128, 1 },
+#endif
 
 	{ NULL,					0, 0, 0, 0, 0, 0 }
 };
@@ -119,9 +123,11 @@
 			fatal("ssh_hmac_start(alg=%d) failed", macalg->alg);
 		mac->key_len = mac->mac_len = ssh_hmac_bytes(macalg->alg);
 	} else {
+#ifdef WITH_OPENSSL
 		mac->mac_len = macalg->len / 8;
 		mac->key_len = macalg->key_len / 8;
 		mac->umac_ctx = NULL;
+#endif
 	}
 	if (macalg->truncatebits != 0)
 		mac->mac_len = macalg->truncatebits / 8;
@@ -157,12 +163,14 @@
 		    ssh_hmac_init(mac->hmac_ctx, mac->key, mac->key_len) < 0)
 			return -1;
 		return 0;
+#ifdef WITH_OPENSSL
 	case SSH_UMAC:
 		mac->umac_ctx = umac_new(mac->key);
 		return 0;
 	case SSH_UMAC128:
 		mac->umac_ctx = umac128_new(mac->key);
 		return 0;
+#endif
 	default:
 		return -1;
 	}
@@ -175,7 +183,10 @@
 		u_char m[EVP_MAX_MD_SIZE];
 		u_int64_t for_align;
 	} u;
-	u_char b[4], nonce[8];
+	u_char b[4];
+#ifdef WITH_OPENSSL
+	u_char nonce[8];
+#endif
 
 	if (mac->mac_len > sizeof(u))
 		fatal("mac_compute: mac too long %u %zu",
@@ -191,6 +202,7 @@
 		    ssh_hmac_final(mac->hmac_ctx, u.m, sizeof(u.m)) < 0)
 			fatal("ssh_hmac failed");
 		break;
+#ifdef WITH_OPENSSL
 	case SSH_UMAC:
 		put_u64(nonce, seqno);
 		umac_update(mac->umac_ctx, data, datalen);
@@ -201,6 +213,7 @@
 		umac128_update(mac->umac_ctx, data, datalen);
 		umac128_final(mac->umac_ctx, u.m, nonce);
 		break;
+#endif
 	default:
 		fatal("mac_compute: unknown MAC type");
 	}
@@ -210,6 +223,7 @@
 void
 mac_clear(Mac *mac)
 {
+#ifdef WITH_OPENSSL
 	if (mac->type == SSH_UMAC) {
 		if (mac->umac_ctx != NULL)
 			umac_delete(mac->umac_ctx);
@@ -217,6 +231,7 @@
 		if (mac->umac_ctx != NULL)
 			umac128_delete(mac->umac_ctx);
 	} else if (mac->hmac_ctx != NULL)
+#endif
 		ssh_hmac_free(mac->hmac_ctx);
 	mac->hmac_ctx = NULL;
 	mac->umac_ctx = NULL;
diff --git a/monitor.c b/monitor.c
index 531c4f9..a38647d 100644
--- a/monitor.c
+++ b/monitor.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: monitor.c,v 1.131 2014/02/02 03:44:31 djm Exp $ */
+/* $OpenBSD: monitor.c,v 1.132 2014/04/29 18:01:49 markus Exp $ */
 /*
  * Copyright 2002 Niels Provos <provos@citi.umich.edu>
  * Copyright 2002 Markus Friedl <markus@openbsd.org>
@@ -56,7 +56,9 @@
 #include <skey.h>
 #endif
 
+#ifdef WITH_OPENSSL
 #include <openssl/dh.h>
+#endif
 
 #include "openbsd-compat/sys-queue.h"
 #include "atomicio.h"
@@ -185,7 +187,10 @@
 static int monitor_read_log(struct monitor *);
 
 static Authctxt *authctxt;
+
+#ifdef WITH_SSH1
 static BIGNUM *ssh1_challenge = NULL;	/* used for ssh1 rsa auth */
+#endif
 
 /* local state for key verify */
 static u_char *key_blob = NULL;
@@ -215,7 +220,9 @@
 #define MON_PERMIT	0x1000	/* Request is permitted */
 
 struct mon_table mon_dispatch_proto20[] = {
+#ifdef WITH_OPENSSL
     {MONITOR_REQ_MODULI, MON_ONCE, mm_answer_moduli},
+#endif
     {MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign},
     {MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow},
     {MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv},
@@ -252,7 +259,9 @@
 };
 
 struct mon_table mon_dispatch_postauth20[] = {
+#ifdef WITH_OPENSSL
     {MONITOR_REQ_MODULI, 0, mm_answer_moduli},
+#endif
     {MONITOR_REQ_SIGN, 0, mm_answer_sign},
     {MONITOR_REQ_PTY, 0, mm_answer_pty},
     {MONITOR_REQ_PTYCLEANUP, 0, mm_answer_pty_cleanup},
@@ -265,6 +274,7 @@
 };
 
 struct mon_table mon_dispatch_proto15[] = {
+#ifdef WITH_SSH1
     {MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow},
     {MONITOR_REQ_SESSKEY, MON_ONCE, mm_answer_sesskey},
     {MONITOR_REQ_SESSID, MON_ONCE, mm_answer_sessid},
@@ -292,10 +302,12 @@
 #ifdef SSH_AUDIT_EVENTS
     {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event},
 #endif
+#endif /* WITH_SSH1 */
     {0, 0, NULL}
 };
 
 struct mon_table mon_dispatch_postauth15[] = {
+#ifdef WITH_SSH1
     {MONITOR_REQ_PTY, MON_ONCE, mm_answer_pty},
     {MONITOR_REQ_PTYCLEANUP, MON_ONCE, mm_answer_pty_cleanup},
     {MONITOR_REQ_TERM, 0, mm_answer_term},
@@ -303,6 +315,7 @@
     {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event},
     {MONITOR_REQ_AUDIT_COMMAND, MON_PERMIT|MON_ONCE, mm_answer_audit_command},
 #endif
+#endif /* WITH_SSH1 */
     {0, 0, NULL}
 };
 
@@ -630,6 +643,7 @@
 	hostbased_chost = NULL;
 }
 
+#ifdef WITH_OPENSSL
 int
 mm_answer_moduli(int sock, Buffer *m)
 {
@@ -664,6 +678,7 @@
 	mm_request_send(sock, MONITOR_ANS_MODULI, m);
 	return (0);
 }
+#endif
 
 extern AuthenticationConnection *auth_conn;
 
@@ -1166,6 +1181,7 @@
 			    cuser, chost);
 			auth_method = "hostbased";
 			break;
+#ifdef WITH_SSH1
 		case MM_RSAHOSTKEY:
 			key->type = KEY_RSA1; /* XXX */
 			allowed = options.rhosts_rsa_authentication &&
@@ -1175,6 +1191,7 @@
 				auth_clear_options();
 			auth_method = "rsa";
 			break;
+#endif
 		default:
 			fatal("%s: unknown key type %d", __func__, type);
 			break;
@@ -1511,6 +1528,7 @@
 	return (0);
 }
 
+#ifdef WITH_SSH1
 int
 mm_answer_sesskey(int sock, Buffer *m)
 {
@@ -1688,6 +1706,7 @@
 
 	return (success);
 }
+#endif
 
 int
 mm_answer_term(int sock, Buffer *req)
@@ -1828,11 +1847,13 @@
 	    timingsafe_bcmp(kex->session_id, session_id2, session_id2_len) != 0)
 		fatal("mm_get_get: internal error: bad session id");
 	kex->we_need = buffer_get_int(m);
+#ifdef WITH_OPENSSL
 	kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server;
 	kex->kex[KEX_DH_GRP14_SHA1] = kexdh_server;
 	kex->kex[KEX_DH_GEX_SHA1] = kexgex_server;
 	kex->kex[KEX_DH_GEX_SHA256] = kexgex_server;
 	kex->kex[KEX_ECDH_SHA2] = kexecdh_server;
+#endif
 	kex->kex[KEX_C25519_SHA256] = kexc25519_server;
 	kex->server = 1;
 	kex->hostkey_type = buffer_get_int(m);
diff --git a/monitor_wrap.c b/monitor_wrap.c
index 1a47e41..45dc169 100644
--- a/monitor_wrap.c
+++ b/monitor_wrap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: monitor_wrap.c,v 1.79 2014/02/02 03:44:31 djm Exp $ */
+/* $OpenBSD: monitor_wrap.c,v 1.80 2014/04/29 18:01:49 markus Exp $ */
 /*
  * Copyright 2002 Niels Provos <provos@citi.umich.edu>
  * Copyright 2002 Markus Friedl <markus@openbsd.org>
@@ -38,14 +38,18 @@
 #include <string.h>
 #include <unistd.h>
 
+#ifdef WITH_OPENSSL
 #include <openssl/bn.h>
 #include <openssl/dh.h>
 #include <openssl/evp.h>
+#endif
 
 #include "openbsd-compat/sys-queue.h"
 #include "xmalloc.h"
 #include "ssh.h"
+#ifdef WITH_OPENSSL
 #include "dh.h"
+#endif
 #include "buffer.h"
 #include "key.h"
 #include "cipher.h"
@@ -174,6 +178,7 @@
 		    rtype, type);
 }
 
+#ifdef WITH_OPENSSL
 DH *
 mm_choose_dh(int min, int nbits, int max)
 {
@@ -207,6 +212,7 @@
 
 	return (dh_new_group(g, p));
 }
+#endif
 
 int
 mm_key_sign(Key *key, u_char **sigp, u_int *lenp, u_char *data, u_int datalen)
@@ -912,6 +918,7 @@
 	buffer_free(&m);
 }
 
+#ifdef WITH_SSH1
 int
 mm_ssh1_session_key(BIGNUM *num)
 {
@@ -931,6 +938,7 @@
 
 	return (rsafail);
 }
+#endif
 
 static void
 mm_chall_setup(char **name, char **infotxt, u_int *numprompts,
@@ -1078,6 +1086,7 @@
 	buffer_free(&m);
 }
 
+#ifdef WITH_SSH1
 int
 mm_auth_rsa_key_allowed(struct passwd *pw, BIGNUM *client_n, Key **rkey)
 {
@@ -1173,6 +1182,7 @@
 
 	return (success);
 }
+#endif
 
 #ifdef SSH_AUDIT_EVENTS
 void
diff --git a/myproposal.h b/myproposal.h
index 94d6f70..020f35c 100644
--- a/myproposal.h
+++ b/myproposal.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: myproposal.h,v 1.38 2014/03/27 23:01:27 markus Exp $ */
+/* $OpenBSD: myproposal.h,v 1.39 2014/04/29 18:01:49 markus Exp $ */
 
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
@@ -77,6 +77,7 @@
 # define SHA2_HMAC_MODES
 #endif
 
+#ifdef WITH_OPENSSL
 #define KEX_SERVER_KEX          \
 	"curve25519-sha256@libssh.org," \
 	KEX_ECDH_METHODS \
@@ -134,6 +135,30 @@
 	"hmac-sha1-96," \
 	"hmac-md5-96"
 
+#else
+
+#define KEX_SERVER_KEX		\
+	"curve25519-sha256@libssh.org"
+#define	KEX_DEFAULT_PK_ALG	\
+	"ssh-ed25519-cert-v01@openssh.com," \
+	"ssh-ed25519"
+#define	KEX_SERVER_ENCRYPT \
+	"aes128-ctr,aes192-ctr,aes256-ctr," \
+	"chacha20-poly1305@openssh.com"
+#define	KEX_SERVER_MAC \
+	"hmac-sha2-256-etm@openssh.com," \
+	"hmac-sha2-512-etm@openssh.com," \
+	"hmac-sha2-256," \
+	"hmac-sha2-512"
+
+#define KEX_CLIENT_KEX KEX_SERVER_KEX
+#define	KEX_CLIENT_ENCRYPT KEX_SERVER_ENCRYPT
+#define KEX_CLIENT_MAC KEX_SERVER_MAC "," \
+	"hmac-sha1-etm@openssh.com," \
+	"hmac-sha1"
+
+#endif /* WITH_OPENSSL */
+
 #define	KEX_DEFAULT_COMP	"none,zlib@openssh.com,zlib"
 #define	KEX_DEFAULT_LANG	""
 
diff --git a/packet.c b/packet.c
index a70acf8..c7c18f3 100644
--- a/packet.c
+++ b/packet.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: packet.c,v 1.194 2014/04/28 03:09:18 djm Exp $ */
+/* $OpenBSD: packet.c,v 1.195 2014/04/29 18:01:49 markus Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -630,6 +630,7 @@
 	buffer_append(&active_state->outgoing_packet, buf, len);
 }
 
+#ifdef WITH_OPENSSL
 void
 packet_put_bignum(BIGNUM * value)
 {
@@ -641,6 +642,7 @@
 {
 	buffer_put_bignum2(&active_state->outgoing_packet, value);
 }
+#endif
 
 #ifdef OPENSSL_HAS_ECC
 void
@@ -1569,6 +1571,7 @@
  * must have been initialized before this call.
  */
 
+#ifdef WITH_OPENSSL
 void
 packet_get_bignum(BIGNUM * value)
 {
@@ -1598,6 +1601,7 @@
 		*length_ptr = bytes;
 	return buffer_ptr(&active_state->incoming_packet);
 }
+#endif
 
 int
 packet_remaining(void)
diff --git a/roaming_client.c b/roaming_client.c
index de049cd..5e5c28b 100644
--- a/roaming_client.c
+++ b/roaming_client.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: roaming_client.c,v 1.7 2014/01/09 23:20:00 djm Exp $ */
+/* $OpenBSD: roaming_client.c,v 1.8 2014/04/29 18:01:49 markus Exp $ */
 /*
  * Copyright (c) 2004-2009 AppGate Network Security AB
  *
@@ -28,9 +28,6 @@
 #include <string.h>
 #include <unistd.h>
 
-#include <openssl/crypto.h>
-#include <openssl/sha.h>
-
 #include "xmalloc.h"
 #include "buffer.h"
 #include "channels.h"
diff --git a/ssh-agent.c b/ssh-agent.c
index f4c0524..bc96ad7 100644
--- a/ssh-agent.c
+++ b/ssh-agent.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-agent.c,v 1.184 2014/03/15 17:28:26 deraadt Exp $ */
+/* $OpenBSD: ssh-agent.c,v 1.185 2014/04/29 18:01:49 markus Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -49,8 +49,10 @@
 #endif
 #include "openbsd-compat/sys-queue.h"
 
+#ifdef WITH_OPENSSL
 #include <openssl/evp.h>
 #include "openbsd-compat/openssl-compat.h"
+#endif
 
 #include <errno.h>
 #include <fcntl.h>
@@ -221,9 +223,11 @@
 	buffer_put_int(&msg, tab->nentries);
 	TAILQ_FOREACH(id, &tab->idlist, next) {
 		if (id->key->type == KEY_RSA1) {
+#ifdef WITH_SSH1
 			buffer_put_int(&msg, BN_num_bits(id->key->rsa->n));
 			buffer_put_bignum(&msg, id->key->rsa->e);
 			buffer_put_bignum(&msg, id->key->rsa->n);
+#endif
 		} else {
 			u_char *blob;
 			u_int blen;
@@ -238,6 +242,7 @@
 	buffer_free(&msg);
 }
 
+#ifdef WITH_SSH1
 /* ssh1 only */
 static void
 process_authentication_challenge1(SocketEntry *e)
@@ -308,6 +313,7 @@
 	BN_clear_free(challenge);
 	buffer_free(&msg);
 }
+#endif
 
 /* ssh2 only */
 static void
@@ -733,6 +739,7 @@
 	case SSH_AGENTC_UNLOCK:
 		process_lock_agent(e, type == SSH_AGENTC_LOCK);
 		break;
+#ifdef WITH_SSH1
 	/* ssh1 */
 	case SSH_AGENTC_RSA_CHALLENGE:
 		process_authentication_challenge1(e);
@@ -750,6 +757,7 @@
 	case SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES:
 		process_remove_all_identities(e, 1);
 		break;
+#endif
 	/* ssh2 */
 	case SSH2_AGENTC_SIGN_REQUEST:
 		process_sign_request2(e);
@@ -1040,7 +1048,9 @@
 	prctl(PR_SET_DUMPABLE, 0);
 #endif
 
+#ifdef WITH_OPENSSL
 	OpenSSL_add_all_algorithms();
+#endif
 
 	__progname = ssh_get_progname(av[0]);
 	seed_rng();
diff --git a/ssh-keygen.c b/ssh-keygen.c
index 85eaf2e..085f1ec 100644
--- a/ssh-keygen.c
+++ b/ssh-keygen.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-keygen.c,v 1.245 2014/04/28 03:09:18 djm Exp $ */
+/* $OpenBSD: ssh-keygen.c,v 1.246 2014/04/29 18:01:49 markus Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -195,6 +195,7 @@
 		fprintf(stderr, "key bits exceeds maximum %d\n", maxbits);
 		exit(1);
 	}
+#ifdef WITH_OPENSSL
 	if (type == KEY_DSA && *bitsp != 1024)
 		fatal("DSA keys must be 1024 bits");
 	else if (type != KEY_ECDSA && type != KEY_ED25519 && *bitsp < 768)
@@ -202,6 +203,7 @@
 	else if (type == KEY_ECDSA && key_ecdsa_bits_to_nid(*bitsp) == -1)
 		fatal("Invalid ECDSA key length - valid lengths are "
 		    "256, 384 or 521 bits");
+#endif
 }
 
 static void
@@ -278,6 +280,7 @@
 #define SSH_COM_PRIVATE_BEGIN		"---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----"
 #define	SSH_COM_PRIVATE_KEY_MAGIC	0x3f6ff9eb
 
+#ifdef WITH_OPENSSL
 static void
 do_convert_to_ssh2(struct passwd *pw, Key *k)
 {
@@ -711,6 +714,7 @@
 	key_free(k);
 	exit(0);
 }
+#endif
 
 static void
 do_print_public(struct passwd *pw)
@@ -1589,7 +1593,9 @@
 		}
 	}
 
+#ifdef ENABLE_PKCS11
 	pkcs11_init(1);
+#endif
 	tmp = tilde_expand_filename(ca_key_path, pw->pw_uid);
 	if (pkcs11provider != NULL) {
 		if ((ca = load_pkcs11_key(tmp)) == NULL)
@@ -1672,7 +1678,9 @@
 		key_free(public);
 		free(out);
 	}
+#ifdef ENABLE_PKCS11
 	pkcs11_terminate();
+#endif
 	exit(0);
 }
 
@@ -1923,6 +1931,7 @@
 	exit(0);
 }
 
+#ifdef WITH_OPENSSL
 static void
 load_krl(const char *path, struct ssh_krl **krlp)
 {
@@ -2145,6 +2154,7 @@
 	ssh_krl_free(krl);
 	exit(ret);
 }
+#endif
 
 static void
 usage(void)
@@ -2448,6 +2458,7 @@
 		printf("Cannot use -l with -H or -R.\n");
 		usage();
 	}
+#ifdef WITH_OPENSSL
 	if (gen_krl) {
 		do_gen_krl(pw, update_krl, argc, argv);
 		return (0);
@@ -2456,6 +2467,7 @@
 		do_check_krl(pw, argc, argv);
 		return (0);
 	}
+#endif
 	if (ca_key_path != NULL) {
 		if (cert_key_id == NULL)
 			fatal("Must specify key id (-I) when certifying");
@@ -2473,10 +2485,12 @@
 		do_change_passphrase(pw);
 	if (change_comment)
 		do_change_comment(pw);
+#ifdef WITH_OPENSSL
 	if (convert_to)
 		do_convert_to(pw);
 	if (convert_from)
 		do_convert_from(pw);
+#endif
 	if (print_public)
 		do_print_public(pw);
 	if (rr_hostname != NULL) {
diff --git a/ssh-keyscan.c b/ssh-keyscan.c
index de45636..3fabfba 100644
--- a/ssh-keyscan.c
+++ b/ssh-keyscan.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-keyscan.c,v 1.91 2014/03/27 23:01:27 markus Exp $ */
+/* $OpenBSD: ssh-keyscan.c,v 1.92 2014/04/29 18:01:49 markus Exp $ */
 /*
  * Copyright 1995, 1996 by David Mazieres <dm@lcs.mit.edu>.
  *
@@ -182,6 +182,7 @@
 	return (tok);
 }
 
+#ifdef WITH_SSH1
 static Key *
 keygrab_ssh1(con *c)
 {
@@ -215,6 +216,7 @@
 
 	return (rsa);
 }
+#endif
 
 static int
 hostjump(Key *hostkey)
@@ -253,11 +255,13 @@
 	    (c->c_keytype == KT_ED25519 ? "ssh-ed25519" :
 	    "ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521"));
 	c->c_kex = kex_setup(myproposal);
+#ifdef WITH_OPENSSL
 	c->c_kex->kex[KEX_DH_GRP1_SHA1] = kexdh_client;
 	c->c_kex->kex[KEX_DH_GRP14_SHA1] = kexdh_client;
 	c->c_kex->kex[KEX_DH_GEX_SHA1] = kexgex_client;
 	c->c_kex->kex[KEX_DH_GEX_SHA256] = kexgex_client;
 	c->c_kex->kex[KEX_ECDH_SHA2] = kexecdh_client;
+#endif
 	c->c_kex->kex[KEX_C25519_SHA256] = kexc25519_client;
 	c->c_kex->verify_host_key = hostjump;
 
@@ -507,10 +511,12 @@
 			c->c_data = xmalloc(c->c_len);
 			c->c_status = CS_KEYS;
 			break;
+#ifdef WITH_SSH1
 		case CS_KEYS:
 			keyprint(c, keygrab_ssh1(c));
 			confree(s);
 			return;
+#endif
 		default:
 			fatal("conread: invalid status %d", c->c_status);
 			break;
diff --git a/ssh-keysign.c b/ssh-keysign.c
index ed24f66..d95bb7d 100644
--- a/ssh-keysign.c
+++ b/ssh-keysign.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-keysign.c,v 1.41 2014/04/19 14:53:48 tedu Exp $ */
+/* $OpenBSD: ssh-keysign.c,v 1.42 2014/04/29 18:01:49 markus Exp $ */
 /*
  * Copyright (c) 2002 Markus Friedl.  All rights reserved.
  *
@@ -209,8 +209,11 @@
 		keys[i] = NULL;
 		if (key_fd[i] == -1)
 			continue;
+#ifdef WITH_OPENSSL
+/* XXX wrong api */
 		keys[i] = key_load_private_pem(key_fd[i], KEY_UNSPEC,
 		    NULL, NULL);
+#endif
 		close(key_fd[i]);
 		if (keys[i] != NULL)
 			found = 1;
diff --git a/ssh-pkcs11.h b/ssh-pkcs11.h
index 59f456a..4d2efda 100644
--- a/ssh-pkcs11.h
+++ b/ssh-pkcs11.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-pkcs11.h,v 1.2 2010/02/24 06:12:53 djm Exp $ */
+/* $OpenBSD: ssh-pkcs11.h,v 1.3 2014/04/29 18:01:49 markus Exp $ */
 /*
  * Copyright (c) 2010 Markus Friedl.  All rights reserved.
  *
@@ -18,3 +18,7 @@
 void	pkcs11_terminate(void);
 int	pkcs11_add_provider(char *, char *, Key ***);
 int	pkcs11_del_provider(char *);
+
+#if !defined(WITH_OPENSSL) && defined(ENABLE_PKCS11)
+#undef ENABLE_PKCS11
+#endif
diff --git a/ssh.c b/ssh.c
index 76040fd..d369b68 100644
--- a/ssh.c
+++ b/ssh.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh.c,v 1.401 2014/02/26 20:18:37 djm Exp $ */
+/* $OpenBSD: ssh.c,v 1.402 2014/04/29 18:01:49 markus Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -71,8 +71,10 @@
 #include <netinet/in.h>
 #include <arpa/inet.h>
 
+#ifdef WITH_OPENSSL
 #include <openssl/evp.h>
 #include <openssl/err.h>
+#endif
 #include "openbsd-compat/openssl-compat.h"
 #include "openbsd-compat/sys-queue.h"
 
@@ -631,7 +633,13 @@
 			break;
 		case 'V':
 			fprintf(stderr, "%s, %s\n",
-			    SSH_RELEASE, SSLeay_version(SSLEAY_VERSION));
+			    SSH_RELEASE,
+#ifdef WITH_OPENSSL
+			    SSLeay_version(SSLEAY_VERSION)
+#else
+			    "without OpenSSL"
+#endif
+			);
 			if (opt == 'V')
 				exit(0);
 			break;
@@ -828,8 +836,10 @@
 
 	host_arg = xstrdup(host);
 
+#ifdef WITH_OPENSSL
 	OpenSSL_add_all_algorithms();
 	ERR_load_crypto_strings();
+#endif
 
 	/* Initialize the command to execute on remote host. */
 	buffer_init(&command);
@@ -876,7 +886,13 @@
 	    SYSLOG_FACILITY_USER, !use_syslog);
 
 	if (debug_flag)
-		logit("%s, %s", SSH_RELEASE, SSLeay_version(SSLEAY_VERSION));
+		logit("%s, %s", SSH_RELEASE,
+#ifdef WITH_OPENSSL
+		    SSLeay_version(SSLEAY_VERSION)
+#else
+		    "without OpenSSL"
+#endif
+		);
 
 	/* Parse the configuration files */
 	process_config_files(pw);
diff --git a/sshconnect.c b/sshconnect.c
index ca6e4cc..5d14ca6 100644
--- a/sshconnect.c
+++ b/sshconnect.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshconnect.c,v 1.247 2014/04/01 03:34:10 djm Exp $ */
+/* $OpenBSD: sshconnect.c,v 1.248 2014/04/29 18:01:49 markus Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -1292,8 +1292,12 @@
 		ssh_kex2(host, hostaddr, port);
 		ssh_userauth2(local_user, server_user, host, sensitive);
 	} else {
+#ifdef WITH_SSH1
 		ssh_kex(host, hostaddr);
 		ssh_userauth1(local_user, server_user, host, sensitive);
+#else
+		fatal("ssh1 is not unsupported");
+#endif
 	}
 	free(local_user);
 }
diff --git a/sshconnect2.c b/sshconnect2.c
index b1aa69c..f71b7d2 100644
--- a/sshconnect2.c
+++ b/sshconnect2.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshconnect2.c,v 1.206 2014/04/18 23:52:25 djm Exp $ */
+/* $OpenBSD: sshconnect2.c,v 1.207 2014/04/29 18:01:49 markus Exp $ */
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
  * Copyright (c) 2008 Damien Miller.  All rights reserved.
@@ -205,11 +205,13 @@
 
 	/* start key exchange */
 	kex = kex_setup(myproposal);
+#ifdef WITH_OPENSSL
 	kex->kex[KEX_DH_GRP1_SHA1] = kexdh_client;
 	kex->kex[KEX_DH_GRP14_SHA1] = kexdh_client;
 	kex->kex[KEX_DH_GEX_SHA1] = kexgex_client;
 	kex->kex[KEX_DH_GEX_SHA256] = kexgex_client;
 	kex->kex[KEX_ECDH_SHA2] = kexecdh_client;
+#endif
 	kex->kex[KEX_C25519_SHA256] = kexc25519_client;
 	kex->client_version_string=client_version_string;
 	kex->server_version_string=server_version_string;
diff --git a/sshd.c b/sshd.c
index b955f19..6e7192c 100644
--- a/sshd.c
+++ b/sshd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshd.c,v 1.425 2014/04/19 14:53:48 tedu Exp $ */
+/* $OpenBSD: sshd.c,v 1.426 2014/04/29 18:01:49 markus Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -72,10 +72,12 @@
 #include <string.h>
 #include <unistd.h>
 
+#ifdef WITH_OPENSSL
 #include <openssl/dh.h>
 #include <openssl/bn.h>
 #include <openssl/rand.h>
 #include "openbsd-compat/openssl-compat.h"
+#endif
 
 #ifdef HAVE_SECUREWARE
 #include <sys/security.h>
@@ -98,7 +100,6 @@
 #include "digest.h"
 #include "key.h"
 #include "kex.h"
-#include "dh.h"
 #include "myproposal.h"
 #include "authfile.h"
 #include "pathnames.h"
@@ -256,7 +257,9 @@
 void destroy_sensitive_data(void);
 void demote_sensitive_data(void);
 
+#ifdef WITH_SSH1
 static void do_ssh1_kex(void);
+#endif
 static void do_ssh2_kex(void);
 
 /*
@@ -931,7 +934,13 @@
 usage(void)
 {
 	fprintf(stderr, "%s, %s\n",
-	    SSH_RELEASE, SSLeay_version(SSLEAY_VERSION));
+	    SSH_RELEASE,
+#ifdef WITH_OPENSSL
+	    SSLeay_version(SSLEAY_VERSION)
+#else
+	    "without OpenSSL"
+#endif
+	);
 	fprintf(stderr,
 "usage: sshd [-46DdeiqTt] [-b bits] [-C connection_spec] [-c host_cert_file]\n"
 "            [-E log_file] [-f config_file] [-g login_grace_time]\n"
@@ -964,6 +973,7 @@
 	buffer_init(&m);
 	buffer_put_cstring(&m, buffer_ptr(conf));
 
+#ifdef WITH_SSH1
 	if (sensitive_data.server_key != NULL &&
 	    sensitive_data.server_key->type == KEY_RSA1) {
 		buffer_put_int(&m, 1);
@@ -974,6 +984,7 @@
 		buffer_put_bignum(&m, sensitive_data.server_key->rsa->p);
 		buffer_put_bignum(&m, sensitive_data.server_key->rsa->q);
 	} else
+#endif
 		buffer_put_int(&m, 0);
 
 #ifndef OPENSSL_PRNG_ONLY
@@ -1010,6 +1021,7 @@
 	free(cp);
 
 	if (buffer_get_int(&m)) {
+#ifdef WITH_SSH1
 		if (sensitive_data.server_key != NULL)
 			key_free(sensitive_data.server_key);
 		sensitive_data.server_key = key_new_private(KEY_RSA1);
@@ -1021,6 +1033,9 @@
 		buffer_get_bignum(&m, sensitive_data.server_key->rsa->q);
 		rsa_generate_additional_parameters(
 		    sensitive_data.server_key->rsa);
+#else
+		fatal("ssh1 not supported");
+#endif
 	}
 
 #ifndef OPENSSL_PRNG_ONLY
@@ -1543,7 +1558,9 @@
 	else
 		closefrom(REEXEC_DEVCRYPTO_RESERVED_FD);
 
+#ifdef WITH_OPENSSL
 	OpenSSL_add_all_algorithms();
+#endif
 
 	/* If requested, redirect the logs to the specified logfile. */
 	if (logfile != NULL) {
@@ -1648,7 +1665,12 @@
 	}
 
 	debug("sshd version %s, %s", SSH_VERSION,
-	    SSLeay_version(SSLEAY_VERSION));
+#ifdef WITH_OPENSSL
+	    SSLeay_version(SSLEAY_VERSION)
+#else
+	    "without OpenSSL"
+#endif
+	);
 
 	/* Store privilege separation user for later use if required. */
 	if ((privsep_pw = getpwnam(SSH_PRIVSEP_USER)) == NULL) {
@@ -1770,6 +1792,8 @@
 		debug("host certificate: #%d type %d %s", j, key->type,
 		    key_type(key));
 	}
+
+#ifdef WITH_SSH1
 	/* Check certain values for sanity. */
 	if (options.protocol & SSH_PROTO_1) {
 		if (options.server_key_bits < 512 ||
@@ -1794,6 +1818,7 @@
 			    options.server_key_bits);
 		}
 	}
+#endif
 
 	if (use_privsep) {
 		struct stat st;
@@ -2077,8 +2102,12 @@
 		do_ssh2_kex();
 		do_authentication2(authctxt);
 	} else {
+#ifdef WITH_SSH1
 		do_ssh1_kex();
 		do_authentication(authctxt);
+#else
+		fatal("ssh1 not supported");
+#endif
 	}
 	/*
 	 * If we use privilege separation, the unprivileged child transfers
@@ -2162,6 +2191,7 @@
 	exit(0);
 }
 
+#ifdef WITH_SSH1
 /*
  * Decrypt session_key_int using our private server key and private host key
  * (key with larger modulus first).
@@ -2211,6 +2241,7 @@
 	}
 	return (rsafail);
 }
+
 /*
  * SSH1 key exchange
  */
@@ -2388,6 +2419,7 @@
 	packet_send();
 	packet_write_wait();
 }
+#endif
 
 void
 sshd_hostkey_sign(Key *privkey, Key *pubkey, u_char **signature, u_int *slen,
@@ -2450,11 +2482,13 @@
 
 	/* start key exchange */
 	kex = kex_setup(myproposal);
+#ifdef WITH_OPENSSL
 	kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server;
 	kex->kex[KEX_DH_GRP14_SHA1] = kexdh_server;
 	kex->kex[KEX_DH_GEX_SHA1] = kexgex_server;
 	kex->kex[KEX_DH_GEX_SHA256] = kexgex_server;
 	kex->kex[KEX_ECDH_SHA2] = kexecdh_server;
+#endif
 	kex->kex[KEX_C25519_SHA256] = kexc25519_server;
 	kex->server = 1;
 	kex->client_version_string=client_version_string;