diff --git a/common-algo.c b/common-algo.c
index acc39642fb8a08cf16f82c4816f9f687c6c13c5b..e65bd183574456312b45c5589c92446d72f70c74 100644
--- a/common-algo.c
+++ b/common-algo.c
@@ -106,6 +106,14 @@ static const struct dropbear_hash dropbear_sha1 =
 static const struct dropbear_hash dropbear_sha1_96 = 
 	{&sha1_desc, 20, 12};
 #endif
+#ifdef DROPBEAR_SHA2_256_HMAC
+static const struct dropbear_hash dropbear_sha2_256 = 
+	{&sha256_desc, 32, 32};
+#endif
+#ifdef DROPBEAR_SHA2_512_HMAC
+static const struct dropbear_hash dropbear_sha2_512 =
+	{&sha512_desc, 64, 64};
+#endif
 #ifdef DROPBEAR_MD5_HMAC
 static const struct dropbear_hash dropbear_md5 = 
 	{&md5_desc, 16, 16};
@@ -156,6 +164,12 @@ algo_type sshciphers[] = {
 };
 
 algo_type sshhashes[] = {
+#ifdef DROPBEAR_SHA2_256_HMAC
+//	{"hmac-sha2-256", 0, &dropbear_sha2_256, 1, NULL},
+#endif
+#ifdef DROPBEAR_SHA2_512_HMAC
+//	{"hmac-sha2-512", 0, &dropbear_sha2_512, 1, NULL},
+#endif
 #ifdef DROPBEAR_SHA1_96_HMAC
 	{"hmac-sha1-96", 0, &dropbear_sha1_96, 1, NULL},
 #endif
diff --git a/common-kex.c b/common-kex.c
index 2b3472b7d6581728c64903c2dcb2b4e6259827e4..c53fdf847b749a388db6e097c7bca1c123e562c5 100644
--- a/common-kex.c
+++ b/common-kex.c
@@ -248,26 +248,28 @@ static void kexinitialise() {
  * already initialised hash_state hs, which should already have processed
  * the dh_K and hash, since these are common. X is the letter 'A', 'B' etc.
  * out must have at least min(SHA1_HASH_SIZE, outlen) bytes allocated.
- * The output will only be expanded once, as we are assured that
- * outlen <= 2*SHA1_HASH_SIZE for all known hashes.
  *
  * See Section 7.2 of rfc4253 (ssh transport) for details */
 static void hashkeys(unsigned char *out, int outlen, 
 		const hash_state * hs, const unsigned char X) {
 
 	hash_state hs2;
-	unsigned char k2[SHA1_HASH_SIZE]; /* used to extending */
+	int offset;
 
 	memcpy(&hs2, hs, sizeof(hash_state));
 	sha1_process(&hs2, &X, 1);
 	sha1_process(&hs2, ses.session_id, SHA1_HASH_SIZE);
 	sha1_done(&hs2, out);
-	if (SHA1_HASH_SIZE < outlen) {
+	for (offset = SHA1_HASH_SIZE; 
+			offset < outlen; 
+			offset += SHA1_HASH_SIZE)
+	{
 		/* need to extend */
+		unsigned char k2[SHA1_HASH_SIZE];
 		memcpy(&hs2, hs, sizeof(hash_state));
-		sha1_process(&hs2, out, SHA1_HASH_SIZE);
+		sha1_process(&hs2, out, offset);
 		sha1_done(&hs2, k2);
-		memcpy(&out[SHA1_HASH_SIZE], k2, outlen - SHA1_HASH_SIZE);
+		memcpy(&out[offset], k2, MIN(outlen - offset, SHA1_HASH_SIZE));
 	}
 }
 
diff --git a/libtomcrypt/src/headers/tomcrypt_custom.h b/libtomcrypt/src/headers/tomcrypt_custom.h
index 12bdb7fc8d5bbce24f7e17bb041542d6818fad05..acc149acb9a0de921d1afcce9cd3c5786a0a0186 100644
--- a/libtomcrypt/src/headers/tomcrypt_custom.h
+++ b/libtomcrypt/src/headers/tomcrypt_custom.h
@@ -118,16 +118,20 @@
 #define LTC_CTR_MODE
 #endif
 
-#if defined(DROPBEAR_DSS) && defined(DSS_PROTOK)
-#define SHA512
-#endif
-
 #define SHA1
 
-#ifdef DROPBEAR_MD5_HMAC
+#ifdef DROPBEAR_MD5
 #define MD5
 #endif
 
+#ifdef DROPBEAR_SHA256
+#define SHA256
+#endif
+
+#ifdef DROPBEAR_SHA512
+#define SHA512
+#endif
+
 #define LTC_HMAC
 
 /* Various tidbits of modern neatoness */
diff --git a/options.h b/options.h
index 14dda0c738a0922456ae45df829f3f74c75b7e81..77a7c7354c19a2308e3e1f7b7e59fcce682f4502 100644
--- a/options.h
+++ b/options.h
@@ -112,6 +112,8 @@ much traffic. */
 
 #define DROPBEAR_SHA1_HMAC
 #define DROPBEAR_SHA1_96_HMAC
+#define DROPBEAR_SHA2_256_HMAC
+#define DROPBEAR_SHA2_512_HMAC
 #define DROPBEAR_MD5_HMAC
 
 /* Hostkey/public key algorithms - at least one required, these are used
diff --git a/sysoptions.h b/sysoptions.h
index e2f53e39d976a3849bc8999ff7e4d66aecbe5a19..74f5dd5b62b0236af4059d250a714d92322953e9 100644
--- a/sysoptions.h
+++ b/sysoptions.h
@@ -90,7 +90,13 @@
 #define MAX_KEY_LEN 32 /* 256 bits for aes256 etc */
 #define MAX_IV_LEN 20 /* must be same as max blocksize, 
 						 and >= SHA1_HASH_SIZE */
+#if defined(DROPBEAR_SHA2_512_HMAC)
+#define MAX_MAC_KEY 64
+#elif defined(DROPBEAR_SHA2_256_HMAC)
+#define MAX_MAC_KEY 32
+#else
 #define MAX_MAC_KEY 20
+#endif
 
 #define MAX_NAME_LEN 64 /* maximum length of a protocol name, isn't
 						   explicitly specified for all protocols (just
@@ -144,6 +150,19 @@
 #define DROPBEAR_TWOFISH
 #endif
 
+#ifdef DROPBEAR_MD5_HMAC
+#define DROPBEAR_MD5
+#endif
+
+#ifdef DROPBEAR_SHA2_256_HMAC
+#define DROPBEAR_SHA256
+#endif
+
+#if (defined(DROPBEAR_DSS) && defined(DSS_PROTOK)) \
+	|| defined(DROPBEAR_SHA2_512_HMAC)
+#define DROPBEAR_SHA512
+#endif
+
 #ifndef ENABLE_X11FWD
 #define DISABLE_X11FWD
 #endif