support --without-openssl at configure time

Disables and removes dependency on OpenSSL. Many features don't
work and the set of crypto options is greatly restricted. This
will only work on system with native arc4random or /dev/urandom.

Considered highly experimental for now.
diff --git a/configure.ac b/configure.ac
index 13e25e9..cb66f54 100644
--- a/configure.ac
+++ b/configure.ac
@@ -121,14 +121,34 @@
 	#include <linux/prctl.h>
 ])
 
+openssl=yes
 ssh1=yes
-AC_ARG_WITH([ssh1],
-	[  --without-ssh1          Disable support for SSH protocol 1],
+AC_ARG_WITH([openssl],
+	[  --without-openssl       Disable use of OpenSSL; use only limited internal crypto **EXPERIMENTAL** ],
 	[  if test "x$withval" = "xno" ; then
+		openssl=no
 		ssh1=no
 	   fi
 	]
 )
+AC_MSG_CHECKING([whether OpenSSL will be used for cryptography])
+if test "x$openssl" = "xyes" ; then
+	AC_MSG_RESULT([yes])
+	AC_DEFINE_UNQUOTED([WITH_OPENSSL], [1], [use libcrypto for cryptography])
+else
+	AC_MSG_RESULT([no])
+fi
+
+AC_ARG_WITH([ssh1],
+	[  --without-ssh1          Disable support for SSH protocol 1],
+	[
+		if test "x$withval" = "xno" ; then
+			ssh1=no
+		elif test "x$openssl" = "xno" ; then
+			AC_MSG_ERROR([Cannot enable SSH protocol 1 with OpenSSL disabled])
+		fi
+	]
+)
 AC_MSG_CHECKING([whether SSH protocol 1 support is enabled])
 if test "x$ssh1" = "xyes" ; then
 	AC_MSG_RESULT([yes])
@@ -1312,7 +1332,7 @@
 		AC_MSG_RESULT([yes])
 	], [
 		AC_MSG_RESULT([no])
-	
+
 ])
 
 AC_CHECK_DECLS([GLOB_NOMATCH], , , [#include <glob.h>])
@@ -1705,10 +1725,13 @@
 	[AC_DEFINE([HAVE_ISBLANK], [1], [Define if you have isblank(3C).])
 ])
 
-# PKCS#11 support requires dlopen() and co
-AC_SEARCH_LIBS([dlopen], [dl],
-    [AC_DEFINE([ENABLE_PKCS11], [], [Enable for PKCS#11 support])]
-)
+# PKCS11 depends on OpenSSL.
+if test "x$openssl" = "xyes" ; then
+	# PKCS#11 support requires dlopen() and co
+	AC_SEARCH_LIBS([dlopen], [dl],
+	    [AC_DEFINE([ENABLE_PKCS11], [], [Enable for PKCS#11 support])]
+	)
+fi
 
 # IRIX has a const char return value for gai_strerror()
 AC_CHECK_FUNCS([gai_strerror], [
@@ -2197,6 +2220,9 @@
 AC_ARG_WITH([ssl-dir],
 	[  --with-ssl-dir=PATH     Specify path to OpenSSL installation ],
 	[
+		if test "x$openssl" = "xno" ; then
+			AC_MSG_ERROR([cannot use --with-ssl-dir when OpenSSL disabled])
+		fi
 		if test "x$withval" != "xno" ; then
 			case "$withval" in
 				# Relative paths
@@ -2229,443 +2255,456 @@
 		fi
 	]
 )
-LIBS="-lcrypto $LIBS"
-AC_TRY_LINK_FUNC([RAND_add], [AC_DEFINE([HAVE_OPENSSL], [1],
-	[Define if your ssl headers are included
-	with #include <openssl/header.h>])],
-	[
-		dnl Check default openssl install dir
-		if test -n "${need_dash_r}"; then
-			LDFLAGS="-L/usr/local/ssl/lib -R/usr/local/ssl/lib ${saved_LDFLAGS}"
-		else
-			LDFLAGS="-L/usr/local/ssl/lib ${saved_LDFLAGS}"
-		fi
-		CPPFLAGS="-I/usr/local/ssl/include ${saved_CPPFLAGS}"
-		AC_CHECK_HEADER([openssl/opensslv.h], ,
-		    [AC_MSG_ERROR([*** OpenSSL headers missing - please install first or check config.log ***])])
-		AC_TRY_LINK_FUNC([RAND_add], [AC_DEFINE([HAVE_OPENSSL])],
-			[
-				AC_MSG_ERROR([*** Can't find recent OpenSSL libcrypto (see config.log for details) ***])
-			]
-		)
-	]
-)
-
-# Determine OpenSSL header version
-AC_MSG_CHECKING([OpenSSL header version])
-AC_RUN_IFELSE(
-	[AC_LANG_PROGRAM([[
-#include <stdio.h>
-#include <string.h>
-#include <openssl/opensslv.h>
-#define DATA "conftest.sslincver"
-	]], [[
-	FILE *fd;
-	int rc;
-
-	fd = fopen(DATA,"w");
-	if(fd == NULL)
-		exit(1);
-
-	if ((rc = fprintf(fd ,"%08x (%s)\n", OPENSSL_VERSION_NUMBER, OPENSSL_VERSION_TEXT)) <0)
-		exit(1);
-
-	exit(0);
-	]])],
-	[
-		ssl_header_ver=`cat conftest.sslincver`
-		AC_MSG_RESULT([$ssl_header_ver])
-	],
-	[
-		AC_MSG_RESULT([not found])
-		AC_MSG_ERROR([OpenSSL version header not found.])
-	],
-	[
-		AC_MSG_WARN([cross compiling: not checking])
-	]
-)
-
-# Determine OpenSSL library version
-AC_MSG_CHECKING([OpenSSL library version])
-AC_RUN_IFELSE(
-	[AC_LANG_PROGRAM([[
-#include <stdio.h>
-#include <string.h>
-#include <openssl/opensslv.h>
-#include <openssl/crypto.h>
-#define DATA "conftest.ssllibver"
-	]], [[
-	FILE *fd;
-	int rc;
-
-	fd = fopen(DATA,"w");
-	if(fd == NULL)
-		exit(1);
-
-	if ((rc = fprintf(fd ,"%08x (%s)\n", SSLeay(),
-	    SSLeay_version(SSLEAY_VERSION))) <0)
-		exit(1);
-
-	exit(0);
-	]])],
-	[
-		ssl_library_ver=`cat conftest.ssllibver`
-		# Check version is supported.
-		case "$ssl_library_ver" in
-			0090[[0-7]]*|009080[[0-5]]*)
-				AC_MSG_ERROR([OpenSSL >= 0.9.8f required (have "$ssl_library_ver")])
-		                ;;
-		        *) ;;
-		esac
-		AC_MSG_RESULT([$ssl_library_ver])
-	],
-	[
-		AC_MSG_RESULT([not found])
-		AC_MSG_ERROR([OpenSSL library not found.])
-	],
-	[
-		AC_MSG_WARN([cross compiling: not checking])
-	]
-)
-
-# XXX make --without-openssl work
-AC_DEFINE_UNQUOTED([WITH_OPENSSL], [1], [use libcrypto for cryptography])
 
 AC_ARG_WITH([openssl-header-check],
 	[  --without-openssl-header-check Disable OpenSSL version consistency check],
-	[  if test "x$withval" = "xno" ; then
-		openssl_check_nonfatal=1
-	   fi
-	]
-)
-
-# Sanity check OpenSSL headers
-AC_MSG_CHECKING([whether OpenSSL's headers match the library])
-AC_RUN_IFELSE(
-	[AC_LANG_PROGRAM([[
-#include <string.h>
-#include <openssl/opensslv.h>
-	]], [[
-	exit(SSLeay() == OPENSSL_VERSION_NUMBER ? 0 : 1);
-	]])],
 	[
-		AC_MSG_RESULT([yes])
-	],
-	[
-		AC_MSG_RESULT([no])
-		if test "x$openssl_check_nonfatal" = "x"; then
-			AC_MSG_ERROR([Your OpenSSL headers do not match your
-library. Check config.log for details.
-If you are sure your installation is consistent, you can disable the check
-by running "./configure --without-openssl-header-check".
-Also see contrib/findssl.sh for help identifying header/library mismatches.
-])
-		else
-			AC_MSG_WARN([Your OpenSSL headers do not match your
-library. Check config.log for details.
-Also see contrib/findssl.sh for help identifying header/library mismatches.])
+		if test "x$withval" = "xno" ; then
+			openssl_check_nonfatal=1
 		fi
-	],
-	[
-		AC_MSG_WARN([cross compiling: not checking])
 	]
 )
 
-AC_MSG_CHECKING([if programs using OpenSSL functions will link])
-AC_LINK_IFELSE(
-	[AC_LANG_PROGRAM([[ #include <openssl/evp.h> ]],
-	[[ SSLeay_add_all_algorithms(); ]])],
-	[
-		AC_MSG_RESULT([yes])
-	],
-	[
-		AC_MSG_RESULT([no])
-		saved_LIBS="$LIBS"
-		LIBS="$LIBS -ldl"
-		AC_MSG_CHECKING([if programs using OpenSSL need -ldl])
-		AC_LINK_IFELSE(
-			[AC_LANG_PROGRAM([[ #include <openssl/evp.h> ]],
-			[[ SSLeay_add_all_algorithms(); ]])],
-			[
-				AC_MSG_RESULT([yes])
-			],
-			[
-				AC_MSG_RESULT([no])
-				LIBS="$saved_LIBS"
-			]
-		)
-	]
-)
-
-AC_CHECK_FUNCS([ \
-	BN_is_prime_ex \
-	DSA_generate_parameters_ex \
-	EVP_DigestInit_ex \
-	EVP_DigestFinal_ex \
-	EVP_MD_CTX_init \
-	EVP_MD_CTX_cleanup \
-	EVP_MD_CTX_copy_ex \
-	HMAC_CTX_init \
-	RSA_generate_key_ex \
-	RSA_get_default_method \
-])
-
+openssl_engine=no
 AC_ARG_WITH([ssl-engine],
 	[  --with-ssl-engine       Enable OpenSSL (hardware) ENGINE support ],
-	[ if test "x$withval" != "xno" ; then
+	[
+		if test "x$openssl" = "xno" ; then
+			AC_MSG_ERROR([cannot use --with-ssl-engine when OpenSSL disabled])
+		fi
+		if test "x$withval" != "xno" ; then
+			openssl_engine=yes
+		fi
+	]
+)
+
+if test "x$openssl" = "xyes" ; then
+	LIBS="-lcrypto $LIBS"
+	AC_TRY_LINK_FUNC([RAND_add], [AC_DEFINE([HAVE_OPENSSL], [1],
+		[Define if your ssl headers are included
+		with #include <openssl/header.h>])],
+		[
+			dnl Check default openssl install dir
+			if test -n "${need_dash_r}"; then
+				LDFLAGS="-L/usr/local/ssl/lib -R/usr/local/ssl/lib ${saved_LDFLAGS}"
+			else
+				LDFLAGS="-L/usr/local/ssl/lib ${saved_LDFLAGS}"
+			fi
+			CPPFLAGS="-I/usr/local/ssl/include ${saved_CPPFLAGS}"
+			AC_CHECK_HEADER([openssl/opensslv.h], ,
+			    [AC_MSG_ERROR([*** OpenSSL headers missing - please install first or check config.log ***])])
+			AC_TRY_LINK_FUNC([RAND_add], [AC_DEFINE([HAVE_OPENSSL])],
+				[
+					AC_MSG_ERROR([*** Can't find recent OpenSSL libcrypto (see config.log for details) ***])
+				]
+			)
+		]
+	)
+
+	# Determine OpenSSL header version
+	AC_MSG_CHECKING([OpenSSL header version])
+	AC_RUN_IFELSE(
+		[AC_LANG_PROGRAM([[
+	#include <stdio.h>
+	#include <string.h>
+	#include <openssl/opensslv.h>
+	#define DATA "conftest.sslincver"
+		]], [[
+		FILE *fd;
+		int rc;
+
+		fd = fopen(DATA,"w");
+		if(fd == NULL)
+			exit(1);
+
+		if ((rc = fprintf(fd ,"%08x (%s)\n", OPENSSL_VERSION_NUMBER, OPENSSL_VERSION_TEXT)) <0)
+			exit(1);
+
+		exit(0);
+		]])],
+		[
+			ssl_header_ver=`cat conftest.sslincver`
+			AC_MSG_RESULT([$ssl_header_ver])
+		],
+		[
+			AC_MSG_RESULT([not found])
+			AC_MSG_ERROR([OpenSSL version header not found.])
+		],
+		[
+			AC_MSG_WARN([cross compiling: not checking])
+		]
+	)
+
+	# Determine OpenSSL library version
+	AC_MSG_CHECKING([OpenSSL library version])
+	AC_RUN_IFELSE(
+		[AC_LANG_PROGRAM([[
+	#include <stdio.h>
+	#include <string.h>
+	#include <openssl/opensslv.h>
+	#include <openssl/crypto.h>
+	#define DATA "conftest.ssllibver"
+		]], [[
+		FILE *fd;
+		int rc;
+
+		fd = fopen(DATA,"w");
+		if(fd == NULL)
+			exit(1);
+
+		if ((rc = fprintf(fd ,"%08x (%s)\n", SSLeay(),
+		    SSLeay_version(SSLEAY_VERSION))) <0)
+			exit(1);
+
+		exit(0);
+		]])],
+		[
+			ssl_library_ver=`cat conftest.ssllibver`
+			# Check version is supported.
+			case "$ssl_library_ver" in
+				0090[[0-7]]*|009080[[0-5]]*)
+					AC_MSG_ERROR([OpenSSL >= 0.9.8f required (have "$ssl_library_ver")])
+			                ;;
+			        *) ;;
+			esac
+			AC_MSG_RESULT([$ssl_library_ver])
+		],
+		[
+			AC_MSG_RESULT([not found])
+			AC_MSG_ERROR([OpenSSL library not found.])
+		],
+		[
+			AC_MSG_WARN([cross compiling: not checking])
+		]
+	)
+
+	# Sanity check OpenSSL headers
+	AC_MSG_CHECKING([whether OpenSSL's headers match the library])
+	AC_RUN_IFELSE(
+		[AC_LANG_PROGRAM([[
+	#include <string.h>
+	#include <openssl/opensslv.h>
+		]], [[
+		exit(SSLeay() == OPENSSL_VERSION_NUMBER ? 0 : 1);
+		]])],
+		[
+			AC_MSG_RESULT([yes])
+		],
+		[
+			AC_MSG_RESULT([no])
+			if test "x$openssl_check_nonfatal" = "x"; then
+				AC_MSG_ERROR([Your OpenSSL headers do not match your
+	library. Check config.log for details.
+	If you are sure your installation is consistent, you can disable the check
+	by running "./configure --without-openssl-header-check".
+	Also see contrib/findssl.sh for help identifying header/library mismatches.
+	])
+			else
+				AC_MSG_WARN([Your OpenSSL headers do not match your
+	library. Check config.log for details.
+	Also see contrib/findssl.sh for help identifying header/library mismatches.])
+			fi
+		],
+		[
+			AC_MSG_WARN([cross compiling: not checking])
+		]
+	)
+
+	AC_MSG_CHECKING([if programs using OpenSSL functions will link])
+	AC_LINK_IFELSE(
+		[AC_LANG_PROGRAM([[ #include <openssl/evp.h> ]],
+		[[ SSLeay_add_all_algorithms(); ]])],
+		[
+			AC_MSG_RESULT([yes])
+		],
+		[
+			AC_MSG_RESULT([no])
+			saved_LIBS="$LIBS"
+			LIBS="$LIBS -ldl"
+			AC_MSG_CHECKING([if programs using OpenSSL need -ldl])
+			AC_LINK_IFELSE(
+				[AC_LANG_PROGRAM([[ #include <openssl/evp.h> ]],
+				[[ SSLeay_add_all_algorithms(); ]])],
+				[
+					AC_MSG_RESULT([yes])
+				],
+				[
+					AC_MSG_RESULT([no])
+					LIBS="$saved_LIBS"
+				]
+			)
+		]
+	)
+
+	AC_CHECK_FUNCS([ \
+		BN_is_prime_ex \
+		DSA_generate_parameters_ex \
+		EVP_DigestInit_ex \
+		EVP_DigestFinal_ex \
+		EVP_MD_CTX_init \
+		EVP_MD_CTX_cleanup \
+		EVP_MD_CTX_copy_ex \
+		HMAC_CTX_init \
+		RSA_generate_key_ex \
+		RSA_get_default_method \
+	])
+
+	if test "x$openssl_engine" = "xyes" ; then
 		AC_MSG_CHECKING([for OpenSSL ENGINE support])
 		AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
-#include <openssl/engine.h>
+	#include <openssl/engine.h>
 			]], [[
-	ENGINE_load_builtin_engines();
-	ENGINE_register_all_complete();
+				ENGINE_load_builtin_engines();
+				ENGINE_register_all_complete();
 			]])],
 			[ AC_MSG_RESULT([yes])
 			  AC_DEFINE([USE_OPENSSL_ENGINE], [1],
 			     [Enable OpenSSL engine support])
 			], [ AC_MSG_ERROR([OpenSSL ENGINE support not found])
 		])
-	  fi ]
-)
+	fi
 
-# Check for OpenSSL without EVP_aes_{192,256}_cbc
-AC_MSG_CHECKING([whether OpenSSL has crippled AES support])
-AC_LINK_IFELSE(
-	[AC_LANG_PROGRAM([[
-#include <string.h>
-#include <openssl/evp.h>
-	]], [[
-	exit(EVP_aes_192_cbc() == NULL || EVP_aes_256_cbc() == NULL);
-	]])],
-	[
-		AC_MSG_RESULT([no])
-	],
-	[
-		AC_MSG_RESULT([yes])
-		AC_DEFINE([OPENSSL_LOBOTOMISED_AES], [1],
-		    [libcrypto is missing AES 192 and 256 bit functions])
-	]
-)
-
-# Check for OpenSSL with EVP_aes_*ctr
-AC_MSG_CHECKING([whether OpenSSL has AES CTR via EVP])
-AC_LINK_IFELSE(
-	[AC_LANG_PROGRAM([[
-#include <string.h>
-#include <openssl/evp.h>
-	]], [[
-	exit(EVP_aes_128_ctr() == NULL ||
-	    EVP_aes_192_cbc() == NULL ||
-	    EVP_aes_256_cbc() == NULL);
-	]])],
-	[
-		AC_MSG_RESULT([yes])
-		AC_DEFINE([OPENSSL_HAVE_EVPCTR], [1],
-		    [libcrypto has EVP AES CTR])
-	],
-	[
-		AC_MSG_RESULT([no])
-	]
-)
-
-# Check for OpenSSL with EVP_aes_*gcm
-AC_MSG_CHECKING([whether OpenSSL has AES GCM via EVP])
-AC_LINK_IFELSE(
-	[AC_LANG_PROGRAM([[
-#include <string.h>
-#include <openssl/evp.h>
-	]], [[
-	exit(EVP_aes_128_gcm() == NULL ||
-	    EVP_aes_256_gcm() == NULL ||
-	    EVP_CTRL_GCM_SET_IV_FIXED == 0 ||
-	    EVP_CTRL_GCM_IV_GEN == 0 ||
-	    EVP_CTRL_GCM_SET_TAG == 0 ||
-	    EVP_CTRL_GCM_GET_TAG == 0 ||
-	    EVP_CIPHER_CTX_ctrl(NULL, 0, 0, NULL) == 0);
-	]])],
-	[
-		AC_MSG_RESULT([yes])
-		AC_DEFINE([OPENSSL_HAVE_EVPGCM], [1],
-		    [libcrypto has EVP AES GCM])
-	],
-	[
-		AC_MSG_RESULT([no])
-		unsupported_algorithms="$unsupported_cipers \
-		   aes128-gcm@openssh.com aes256-gcm@openssh.com"
-	]
-)
-
-AC_SEARCH_LIBS([EVP_CIPHER_CTX_ctrl], [crypto],
-	[AC_DEFINE([HAVE_EVP_CIPHER_CTX_CTRL], [1],
-	    [Define if libcrypto has EVP_CIPHER_CTX_ctrl])])
-
-AC_MSG_CHECKING([if EVP_DigestUpdate returns an int])
-AC_LINK_IFELSE(
-	[AC_LANG_PROGRAM([[
-#include <string.h>
-#include <openssl/evp.h>
-	]], [[
-	if(EVP_DigestUpdate(NULL, NULL,0))
-		exit(0);
-	]])],
-	[
-		AC_MSG_RESULT([yes])
-	],
-	[
-		AC_MSG_RESULT([no])
-		AC_DEFINE([OPENSSL_EVP_DIGESTUPDATE_VOID], [1],
-		    [Define if EVP_DigestUpdate returns void])
-	]
-)
-
-# Some systems want crypt() from libcrypt, *not* the version in OpenSSL,
-# because the system crypt() is more featureful.
-if test "x$check_for_libcrypt_before" = "x1"; then
-	AC_CHECK_LIB([crypt], [crypt])
-fi
-
-# Some Linux systems (Slackware) need crypt() from libcrypt, *not* the
-# version in OpenSSL.
-if test "x$check_for_libcrypt_later" = "x1"; then
-	AC_CHECK_LIB([crypt], [crypt], [LIBS="$LIBS -lcrypt"])
-fi
-AC_CHECK_FUNCS([crypt DES_crypt])
-
-# Search for SHA256 support in libc and/or OpenSSL
-AC_CHECK_FUNCS([SHA256_Update EVP_sha256], ,
-    [unsupported_algorithms="$unsupported_algorithms \
-	hmac-sha2-256 hmac-sha2-512 \
-	diffie-hellman-group-exchange-sha256 \
-	hmac-sha2-256-etm@openssh.com hmac-sha2-512-etm@openssh.com"
-     ]
-)
-# Search for RIPE-MD support in OpenSSL
-AC_CHECK_FUNCS([EVP_ripemd160], ,
-    [unsupported_algorithms="$unsupported_algorithms \
-	hmac-ripemd160
-	hmac-ripemd160@openssh.com
-	hmac-ripemd160-etm@openssh.com"
-     ]
-)
-
-# Check complete ECC support in OpenSSL
-AC_MSG_CHECKING([whether OpenSSL has NID_X9_62_prime256v1])
-AC_LINK_IFELSE(
-	[AC_LANG_PROGRAM([[
-#include <openssl/ec.h>
-#include <openssl/ecdh.h>
-#include <openssl/ecdsa.h>
-#include <openssl/evp.h>
-#include <openssl/objects.h>
-#include <openssl/opensslv.h>
-#if OPENSSL_VERSION_NUMBER < 0x0090807f /* 0.9.8g */
-# error "OpenSSL < 0.9.8g has unreliable ECC code"
-#endif
-	]], [[
-	EC_KEY *e = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
-	const EVP_MD *m = EVP_sha256(); /* We need this too */
-	]])],
-	[ AC_MSG_RESULT([yes])
-	  enable_nistp256=1 ],
-	[ AC_MSG_RESULT([no]) ]
-)
-
-AC_MSG_CHECKING([whether OpenSSL has NID_secp384r1])
-AC_LINK_IFELSE(
-	[AC_LANG_PROGRAM([[
-#include <openssl/ec.h>
-#include <openssl/ecdh.h>
-#include <openssl/ecdsa.h>
-#include <openssl/evp.h>
-#include <openssl/objects.h>
-#include <openssl/opensslv.h>
-#if OPENSSL_VERSION_NUMBER < 0x0090807f /* 0.9.8g */
-# error "OpenSSL < 0.9.8g has unreliable ECC code"
-#endif
-	]], [[
-	EC_KEY *e = EC_KEY_new_by_curve_name(NID_secp384r1);
-	const EVP_MD *m = EVP_sha384(); /* We need this too */
-	]])],
-	[ AC_MSG_RESULT([yes])
-	  enable_nistp384=1 ],
-	[ AC_MSG_RESULT([no]) ]
-)
-
-AC_MSG_CHECKING([whether OpenSSL has NID_secp521r1])
-AC_LINK_IFELSE(
-	[AC_LANG_PROGRAM([[
-#include <openssl/ec.h>
-#include <openssl/ecdh.h>
-#include <openssl/ecdsa.h>
-#include <openssl/evp.h>
-#include <openssl/objects.h>
-#include <openssl/opensslv.h>
-#if OPENSSL_VERSION_NUMBER < 0x0090807f /* 0.9.8g */
-# error "OpenSSL < 0.9.8g has unreliable ECC code"
-#endif
-	]], [[
-	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_MSG_CHECKING([if OpenSSL's NID_secp521r1 is functional])
-	  AC_RUN_IFELSE(
+	# Check for OpenSSL without EVP_aes_{192,256}_cbc
+	AC_MSG_CHECKING([whether OpenSSL has crippled AES support])
+	AC_LINK_IFELSE(
 		[AC_LANG_PROGRAM([[
-#include <openssl/ec.h>
-#include <openssl/ecdh.h>
-#include <openssl/ecdsa.h>
-#include <openssl/evp.h>
-#include <openssl/objects.h>
-#include <openssl/opensslv.h>
-		]],[[
-		EC_KEY *e = EC_KEY_new_by_curve_name(NID_secp521r1);
-		const EVP_MD *m = EVP_sha512(); /* We need this too */
-		exit(e == NULL || m == NULL);
+	#include <string.h>
+	#include <openssl/evp.h>
+		]], [[
+		exit(EVP_aes_192_cbc() == NULL || EVP_aes_256_cbc() == NULL);
+		]])],
+		[
+			AC_MSG_RESULT([no])
+		],
+		[
+			AC_MSG_RESULT([yes])
+			AC_DEFINE([OPENSSL_LOBOTOMISED_AES], [1],
+			    [libcrypto is missing AES 192 and 256 bit functions])
+		]
+	)
+
+	# Check for OpenSSL with EVP_aes_*ctr
+	AC_MSG_CHECKING([whether OpenSSL has AES CTR via EVP])
+	AC_LINK_IFELSE(
+		[AC_LANG_PROGRAM([[
+	#include <string.h>
+	#include <openssl/evp.h>
+		]], [[
+		exit(EVP_aes_128_ctr() == NULL ||
+		    EVP_aes_192_cbc() == NULL ||
+		    EVP_aes_256_cbc() == NULL);
+		]])],
+		[
+			AC_MSG_RESULT([yes])
+			AC_DEFINE([OPENSSL_HAVE_EVPCTR], [1],
+			    [libcrypto has EVP AES CTR])
+		],
+		[
+			AC_MSG_RESULT([no])
+		]
+	)
+
+	# Check for OpenSSL with EVP_aes_*gcm
+	AC_MSG_CHECKING([whether OpenSSL has AES GCM via EVP])
+	AC_LINK_IFELSE(
+		[AC_LANG_PROGRAM([[
+	#include <string.h>
+	#include <openssl/evp.h>
+		]], [[
+		exit(EVP_aes_128_gcm() == NULL ||
+		    EVP_aes_256_gcm() == NULL ||
+		    EVP_CTRL_GCM_SET_IV_FIXED == 0 ||
+		    EVP_CTRL_GCM_IV_GEN == 0 ||
+		    EVP_CTRL_GCM_SET_TAG == 0 ||
+		    EVP_CTRL_GCM_GET_TAG == 0 ||
+		    EVP_CIPHER_CTX_ctrl(NULL, 0, 0, NULL) == 0);
+		]])],
+		[
+			AC_MSG_RESULT([yes])
+			AC_DEFINE([OPENSSL_HAVE_EVPGCM], [1],
+			    [libcrypto has EVP AES GCM])
+		],
+		[
+			AC_MSG_RESULT([no])
+			unsupported_algorithms="$unsupported_cipers \
+			   aes128-gcm@openssh.com aes256-gcm@openssh.com"
+		]
+	)
+
+	AC_SEARCH_LIBS([EVP_CIPHER_CTX_ctrl], [crypto],
+		[AC_DEFINE([HAVE_EVP_CIPHER_CTX_CTRL], [1],
+		    [Define if libcrypto has EVP_CIPHER_CTX_ctrl])])
+
+	AC_MSG_CHECKING([if EVP_DigestUpdate returns an int])
+	AC_LINK_IFELSE(
+		[AC_LANG_PROGRAM([[
+	#include <string.h>
+	#include <openssl/evp.h>
+		]], [[
+		if(EVP_DigestUpdate(NULL, NULL,0))
+			exit(0);
+		]])],
+		[
+			AC_MSG_RESULT([yes])
+		],
+		[
+			AC_MSG_RESULT([no])
+			AC_DEFINE([OPENSSL_EVP_DIGESTUPDATE_VOID], [1],
+			    [Define if EVP_DigestUpdate returns void])
+		]
+	)
+
+	# Some systems want crypt() from libcrypt, *not* the version in OpenSSL,
+	# because the system crypt() is more featureful.
+	if test "x$check_for_libcrypt_before" = "x1"; then
+		AC_CHECK_LIB([crypt], [crypt])
+	fi
+
+	# Some Linux systems (Slackware) need crypt() from libcrypt, *not* the
+	# version in OpenSSL.
+	if test "x$check_for_libcrypt_later" = "x1"; then
+		AC_CHECK_LIB([crypt], [crypt], [LIBS="$LIBS -lcrypt"])
+	fi
+
+	# Search for SHA256 support in libc and/or OpenSSL
+	AC_CHECK_FUNCS([SHA256_Update EVP_sha256], ,
+	    [unsupported_algorithms="$unsupported_algorithms \
+		hmac-sha2-256 hmac-sha2-512 \
+		diffie-hellman-group-exchange-sha256 \
+		hmac-sha2-256-etm@openssh.com hmac-sha2-512-etm@openssh.com"
+	     ]
+	)
+	# Search for RIPE-MD support in OpenSSL
+	AC_CHECK_FUNCS([EVP_ripemd160], ,
+	    [unsupported_algorithms="$unsupported_algorithms \
+		hmac-ripemd160
+		hmac-ripemd160@openssh.com
+		hmac-ripemd160-etm@openssh.com"
+	     ]
+	)
+
+	# Check complete ECC support in OpenSSL
+	AC_MSG_CHECKING([whether OpenSSL has NID_X9_62_prime256v1])
+	AC_LINK_IFELSE(
+		[AC_LANG_PROGRAM([[
+	#include <openssl/ec.h>
+	#include <openssl/ecdh.h>
+	#include <openssl/ecdsa.h>
+	#include <openssl/evp.h>
+	#include <openssl/objects.h>
+	#include <openssl/opensslv.h>
+	#if OPENSSL_VERSION_NUMBER < 0x0090807f /* 0.9.8g */
+	# error "OpenSSL < 0.9.8g has unreliable ECC code"
+	#endif
+		]], [[
+		EC_KEY *e = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
+		const EVP_MD *m = EVP_sha256(); /* We need this too */
 		]])],
 		[ AC_MSG_RESULT([yes])
-		  enable_nistp521=1 ],
-		[ AC_MSG_RESULT([no]) ],
-		[ AC_MSG_WARN([cross-compiling: assuming yes])
-		  enable_nistp521=1 ]
-	  )],
-	AC_MSG_RESULT([no])
-)
+		  enable_nistp256=1 ],
+		[ AC_MSG_RESULT([no]) ]
+	)
 
-COMMENT_OUT_ECC="#no ecc#"
-TEST_SSH_ECC=no
+	AC_MSG_CHECKING([whether OpenSSL has NID_secp384r1])
+	AC_LINK_IFELSE(
+		[AC_LANG_PROGRAM([[
+	#include <openssl/ec.h>
+	#include <openssl/ecdh.h>
+	#include <openssl/ecdsa.h>
+	#include <openssl/evp.h>
+	#include <openssl/objects.h>
+	#include <openssl/opensslv.h>
+	#if OPENSSL_VERSION_NUMBER < 0x0090807f /* 0.9.8g */
+	# error "OpenSSL < 0.9.8g has unreliable ECC code"
+	#endif
+		]], [[
+		EC_KEY *e = EC_KEY_new_by_curve_name(NID_secp384r1);
+		const EVP_MD *m = EVP_sha384(); /* We need this too */
+		]])],
+		[ AC_MSG_RESULT([yes])
+		  enable_nistp384=1 ],
+		[ AC_MSG_RESULT([no]) ]
+	)
 
-if test x$enable_nistp256 = x1 || test x$enable_nistp384 = x1 || \
-    test x$enable_nistp521 = x1; then
-	AC_DEFINE(OPENSSL_HAS_ECC, [1], [OpenSSL has ECC])
-fi
-if test x$enable_nistp256 = x1; then
-	AC_DEFINE([OPENSSL_HAS_NISTP256], [1],
-	    [libcrypto has NID_X9_62_prime256v1])
-	TEST_SSH_ECC=yes
-	COMMENT_OUT_ECC=""
-else
-	unsupported_algorithms="$unsupported_algorithms ecdsa-sha2-nistp256 \
-	    ecdh-sha2-nistp256 ecdsa-sha2-nistp256-cert-v01@openssh.com"
-fi
-if test x$enable_nistp384 = x1; then
-	AC_DEFINE([OPENSSL_HAS_NISTP384], [1], [libcrypto has NID_secp384r1])
-	TEST_SSH_ECC=yes
-	COMMENT_OUT_ECC=""
-else
-	unsupported_algorithms="$unsupported_algorithms ecdsa-sha2-nistp384 \
-	    ecdh-sha2-nistp384 ecdsa-sha2-nistp384-cert-v01@openssh.com"
-fi
-if test x$enable_nistp521 = x1; then
-	AC_DEFINE([OPENSSL_HAS_NISTP521], [1], [libcrypto has NID_secp521r1])
-	TEST_SSH_ECC=yes
-	COMMENT_OUT_ECC=""
-else
-	unsupported_algorithms="$unsupported_algorithms ecdh-sha2-nistp521 \
-	    ecdsa-sha2-nistp521 ecdsa-sha2-nistp521-cert-v01@openssh.com"
-fi
+	AC_MSG_CHECKING([whether OpenSSL has NID_secp521r1])
+	AC_LINK_IFELSE(
+		[AC_LANG_PROGRAM([[
+	#include <openssl/ec.h>
+	#include <openssl/ecdh.h>
+	#include <openssl/ecdsa.h>
+	#include <openssl/evp.h>
+	#include <openssl/objects.h>
+	#include <openssl/opensslv.h>
+	#if OPENSSL_VERSION_NUMBER < 0x0090807f /* 0.9.8g */
+	# error "OpenSSL < 0.9.8g has unreliable ECC code"
+	#endif
+		]], [[
+		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_MSG_CHECKING([if OpenSSL's NID_secp521r1 is functional])
+		  AC_RUN_IFELSE(
+			[AC_LANG_PROGRAM([[
+	#include <openssl/ec.h>
+	#include <openssl/ecdh.h>
+	#include <openssl/ecdsa.h>
+	#include <openssl/evp.h>
+	#include <openssl/objects.h>
+	#include <openssl/opensslv.h>
+			]],[[
+			EC_KEY *e = EC_KEY_new_by_curve_name(NID_secp521r1);
+			const EVP_MD *m = EVP_sha512(); /* We need this too */
+			exit(e == NULL || m == NULL);
+			]])],
+			[ AC_MSG_RESULT([yes])
+			  enable_nistp521=1 ],
+			[ AC_MSG_RESULT([no]) ],
+			[ AC_MSG_WARN([cross-compiling: assuming yes])
+			  enable_nistp521=1 ]
+		  )],
+		AC_MSG_RESULT([no])
+	)
 
-AC_SUBST([TEST_SSH_ECC])
-AC_SUBST([COMMENT_OUT_ECC])
+	COMMENT_OUT_ECC="#no ecc#"
+	TEST_SSH_ECC=no
+
+	if test x$enable_nistp256 = x1 || test x$enable_nistp384 = x1 || \
+	    test x$enable_nistp521 = x1; then
+		AC_DEFINE(OPENSSL_HAS_ECC, [1], [OpenSSL has ECC])
+	fi
+	if test x$enable_nistp256 = x1; then
+		AC_DEFINE([OPENSSL_HAS_NISTP256], [1],
+		    [libcrypto has NID_X9_62_prime256v1])
+		TEST_SSH_ECC=yes
+		COMMENT_OUT_ECC=""
+	else
+		unsupported_algorithms="$unsupported_algorithms ecdsa-sha2-nistp256 \
+		    ecdh-sha2-nistp256 ecdsa-sha2-nistp256-cert-v01@openssh.com"
+	fi
+	if test x$enable_nistp384 = x1; then
+		AC_DEFINE([OPENSSL_HAS_NISTP384], [1], [libcrypto has NID_secp384r1])
+		TEST_SSH_ECC=yes
+		COMMENT_OUT_ECC=""
+	else
+		unsupported_algorithms="$unsupported_algorithms ecdsa-sha2-nistp384 \
+		    ecdh-sha2-nistp384 ecdsa-sha2-nistp384-cert-v01@openssh.com"
+	fi
+	if test x$enable_nistp521 = x1; then
+		AC_DEFINE([OPENSSL_HAS_NISTP521], [1], [libcrypto has NID_secp521r1])
+		TEST_SSH_ECC=yes
+		COMMENT_OUT_ECC=""
+	else
+		unsupported_algorithms="$unsupported_algorithms ecdh-sha2-nistp521 \
+		    ecdsa-sha2-nistp521 ecdsa-sha2-nistp521-cert-v01@openssh.com"
+	fi
+
+	AC_SUBST([TEST_SSH_ECC])
+	AC_SUBST([COMMENT_OUT_ECC])
+else
+	AC_CHECK_LIB([crypt], [crypt], [LIBS="$LIBS -lcrypt"])
+	AC_CHECK_FUNCS([crypt DES_crypt])
+fi
 
 AC_CHECK_FUNCS([ \
 	arc4random \
@@ -2687,28 +2726,30 @@
 ### Configure cryptographic random number support
 
 # Check wheter OpenSSL seeds itself
-AC_MSG_CHECKING([whether OpenSSL's PRNG is internally seeded])
-AC_RUN_IFELSE(
-	[AC_LANG_PROGRAM([[
-#include <string.h>
-#include <openssl/rand.h>
-	]], [[
-	exit(RAND_status() == 1 ? 0 : 1);
-	]])],
-	[
-		OPENSSL_SEEDS_ITSELF=yes
-		AC_MSG_RESULT([yes])
-	],
-	[
-		AC_MSG_RESULT([no])
-	],
-	[
-		AC_MSG_WARN([cross compiling: assuming yes])
-		# This is safe, since we will fatal() at runtime if
-		# OpenSSL is not seeded correctly.
-		OPENSSL_SEEDS_ITSELF=yes
-	]
-)
+if test "x$openssl" = "xyes" ; then
+	AC_MSG_CHECKING([whether OpenSSL's PRNG is internally seeded])
+	AC_RUN_IFELSE(
+		[AC_LANG_PROGRAM([[
+	#include <string.h>
+	#include <openssl/rand.h>
+		]], [[
+		exit(RAND_status() == 1 ? 0 : 1);
+		]])],
+		[
+			OPENSSL_SEEDS_ITSELF=yes
+			AC_MSG_RESULT([yes])
+		],
+		[
+			AC_MSG_RESULT([no])
+		],
+		[
+			AC_MSG_WARN([cross compiling: assuming yes])
+			# This is safe, since we will fatal() at runtime if
+			# OpenSSL is not seeded correctly.
+			OPENSSL_SEEDS_ITSELF=yes
+		]
+	)
+fi
 
 # PRNGD TCP socket
 AC_ARG_WITH([prngd-port],
@@ -2790,8 +2831,10 @@
 	RAND_MSG="PRNGd socket $PRNGD_SOCKET"
 elif test ! -z "$OPENSSL_SEEDS_ITSELF" ; then
 	AC_DEFINE([OPENSSL_PRNG_ONLY], [1],
-		[Define if you want OpenSSL's internally seeded PRNG only])
+		[Define if you want the OpenSSL internally seeded PRNG only])
 	RAND_MSG="OpenSSL internal ONLY"
+elif test "x$openssl" = "xno" ; then
+	AC_MSG_WARN([OpenSSH will use /dev/urandom as a source of random numbers. It will fail if this device is not supported or accessible])
 else
 	AC_MSG_ERROR([OpenSSH has no source of random numbers. Please configure OpenSSL with an entropy source or re-run configure using one of the --with-prngd-port or --with-prngd-socket options])
 fi
@@ -2853,7 +2896,7 @@
 				which takes only one argument to pam_strerror])
 			AC_MSG_RESULT([yes])
 			PAM_MSG="yes (old library)"
-		
+
 	])
 fi