diff -Nur ipmitool.sav/config.h.in ipmitool/config.h.in
--- ipmitool.sav/config.h.in	2011-05-03 17:42:34.700043000 +0200
+++ ipmitool/config.h.in	2011-05-04 10:10:12.680043002 +0200
@@ -27,6 +27,9 @@
 /* Define to 1 if libcrypto supports MD5. */
 #undef HAVE_CRYPTO_MD5
 
+/* Define to 1 if libcrypto supports SHA256. */
+#undef HAVE_CRYPTO_SHA256
+
 /* Define to 1 if you have the <dlfcn.h> header file. */
 #undef HAVE_DLFCN_H
 
diff -Nur ipmitool.sav/configure ipmitool/configure
--- ipmitool.sav/configure	2011-05-04 13:52:23.828043000 +0200
+++ ipmitool/configure	2011-05-04 14:21:38.296043002 +0200
@@ -11589,6 +11589,55 @@
 fi
 
 
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for EVP_sha256 in -lcrypto" >&5
+$as_echo_n "checking for EVP_sha256 in -lcrypto... " >&6; }
+if test "${ac_cv_lib_crypto_EVP_sha256+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcrypto -lcrypto $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char EVP_sha256 ();
+int
+main ()
+{
+return EVP_sha256 ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_crypto_EVP_sha256=yes
+else
+  ac_cv_lib_crypto_EVP_sha256=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypto_EVP_sha256" >&5
+$as_echo "$ac_cv_lib_crypto_EVP_sha256" >&6; }
+if test "x$ac_cv_lib_crypto_EVP_sha256" = x""yes; then :
+  if test "x$enable_internal_sha256" != "xyes"; then
+	    if test "x$have_crypto" != "xyes"; then
+	    	LIBS="$LIBS -lcrypto"
+		have_sha256=yes
+	    fi
+
+$as_echo "#define HAVE_CRYPTO_SHA256 1" >>confdefs.h
+
+	fi
+fi
+
+
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for MD5_Init in -lcrypto" >&5
 $as_echo_n "checking for MD5_Init in -lcrypto... " >&6; }
 if test "${ac_cv_lib_crypto_MD5_Init+set}" = set; then :
diff -Nur ipmitool.sav/configure.in ipmitool/configure.in
--- ipmitool.sav/configure.in	2009-11-25 22:19:44.000000000 +0100
+++ ipmitool/configure.in	2011-05-03 17:51:47.901421000 +0200
@@ -129,6 +129,15 @@
 	    have_crypto=yes; LIBS="$LIBS -lcrypto"
 	fi], [have_crypto=no], [-lcrypto])
 
+AC_CHECK_LIB([crypto], [EVP_sha256],
+	[if test "x$enable_internal_sha256" != "xyes"; then
+	    if test "x$have_crypto" != "xyes"; then
+	    	LIBS="$LIBS -lcrypto"
+		have_sha256=yes
+	    fi
+	    AC_DEFINE(HAVE_CRYPTO_SHA256, [1], [Define to 1 if libcrypto supports SHA256.])
+	fi], [], [-lcrypto])
+
 AC_CHECK_LIB([crypto], [MD5_Init],
 	[if test "x$enable_internal_md5" != "xyes"; then
 	    if test "x$have_crypto" != "xyes"; then
diff -Nur ipmitool.sav/include/ipmitool/ipmi_constants.h ipmitool/include/ipmitool/ipmi_constants.h
--- ipmitool.sav/include/ipmitool/ipmi_constants.h	2007-08-29 22:17:50.000000000 +0200
+++ ipmitool/include/ipmitool/ipmi_constants.h	2011-05-04 10:20:16.787445000 +0200
@@ -118,12 +118,14 @@
 #define IPMI_AUTH_RAKP_NONE         0x00
 #define IPMI_AUTH_RAKP_HMAC_SHA1    0x01
 #define IPMI_AUTH_RAKP_HMAC_MD5     0x02
+#define IPMI_AUTH_RAKP_HMAC_SHA256  0x03
 
 /* From table 13-18 of the IPMI v2 specification */
 #define IPMI_INTEGRITY_NONE         0x00
 #define IPMI_INTEGRITY_HMAC_SHA1_96 0x01
 #define IPMI_INTEGRITY_HMAC_MD5_128 0x02
 #define IPMI_INTEGRITY_MD5_128      0x03
+#define IPMI_INTEGRITY_HMAC_SHA256_128 0x04
 
 /* From table 13-19 of the IPMI v2 specfication */
 #define IPMI_CRYPT_NONE             0x00
diff -Nur ipmitool.sav/include/ipmitool/ipmi.h ipmitool/include/ipmitool/ipmi.h
--- ipmitool.sav/include/ipmitool/ipmi.h	2009-08-20 07:11:06.000000000 +0200
+++ ipmitool/include/ipmitool/ipmi.h	2011-05-04 10:20:00.500897000 +0200
@@ -45,6 +45,10 @@
 # include <config.h>
 #endif
 
+#ifndef EVP_MAX_MD_SIZE
+#include <openssl/evp.h>
+#endif
+
 #define IPMI_BUF_SIZE 1024
 
 #if HAVE_PRAGMA_PACK
@@ -211,13 +215,13 @@
 			uint32_t console_id;
 			uint8_t bmc_rand[16];	/* Random number generated by the BMC */
 			uint8_t bmc_guid[16];
-			uint8_t key_exchange_auth_code[20];
+			uint8_t key_exchange_auth_code[EVP_MAX_MD_SIZE];
 		} rakp2_message;
 		struct {
 			uint8_t message_tag;
 			uint8_t rakp_return_code;
 			uint32_t console_id;
-			uint8_t integrity_check_value[20];
+			uint8_t integrity_check_value[EVP_MAX_MD_SIZE];
 		} rakp4_message;
 		struct {
 			uint8_t packet_sequence_number;
diff -Nur ipmitool.sav/include/ipmitool/ipmi_intf.h ipmitool/include/ipmitool/ipmi_intf.h
--- ipmitool.sav/include/ipmitool/ipmi_intf.h	2010-05-02 15:44:50.000000000 +0200
+++ ipmitool/include/ipmitool/ipmi_intf.h	2011-05-04 10:21:15.849485000 +0200
@@ -42,6 +42,7 @@
 #include <sys/socket.h>
 #include <netinet/in.h>
 
+#include <openssl/evp.h> 
 /*
  * An enumeration that describes every possible session state for
  * an IPMIv2 / RMCP+ session.
@@ -58,8 +59,8 @@
 };
 
 
-#define IPMI_AUTHCODE_BUFFER_SIZE 20
-#define IPMI_SIK_BUFFER_SIZE      20
+#define IPMI_AUTHCODE_BUFFER_SIZE 20 /* KG or KUID */
+#define IPMI_SIK_BUFFER_SIZE      EVP_MAX_MD_SIZE
 #define IPMI_KG_BUFFER_SIZE       21 /* key plus null byte */
 
 struct ipmi_session {
@@ -124,10 +125,13 @@
 		uint8_t requested_role;   /* As sent in the RAKP 1 message */
 		uint8_t rakp2_return_code;
 
-		uint8_t sik[IPMI_SIK_BUFFER_SIZE]; /* Session integrity key */
+		uint8_t  sik[EVP_MAX_MD_SIZE];      /* Session integrity key */
+		uint32_t sik_len;                   /* Session Integrity key length */
 		uint8_t kg[IPMI_KG_BUFFER_SIZE];   /* BMC key */
-		uint8_t k1[20];   /* Used for Integrity checking? */
-		uint8_t k2[20];   /* First 16 bytes used for AES  */
+		uint8_t  k1[EVP_MAX_MD_SIZE];       /* Used for Integrity checking? */
+		uint32_t k1_len;                    /* K1 key length */
+		uint8_t  k2[EVP_MAX_MD_SIZE];       /* First 16 bytes used for AES  */
+		uint32_t k2_len;                    /* K2 key length */
 	} v2_data;
 
 
diff -Nur ipmitool.sav/lib/ipmi_strings.c ipmitool/lib/ipmi_strings.c
--- ipmitool.sav/lib/ipmi_strings.c	2010-02-01 22:38:52.000000000 +0100
+++ ipmitool/lib/ipmi_strings.c	2011-05-04 13:39:42.469617000 +0200
@@ -406,6 +406,9 @@
 	{ IPMI_AUTH_RAKP_NONE,      "none"      },
 	{ IPMI_AUTH_RAKP_HMAC_SHA1, "hmac_sha1" },
 	{ IPMI_AUTH_RAKP_HMAC_MD5,  "hmac_md5"  },
+#ifdef HAVE_CRYPTO_SHA256
+	{ IPMI_AUTH_RAKP_HMAC_SHA256, "hmac_sha256"  },
+#endif // HAVE_CRYPTO_SHA256
 	{ 0x00, NULL }
 };
 
@@ -414,6 +417,9 @@
 	{ IPMI_INTEGRITY_HMAC_SHA1_96, "hmac_sha1_96" },
 	{ IPMI_INTEGRITY_HMAC_MD5_128, "hmac_md5_128" },
 	{ IPMI_INTEGRITY_MD5_128 ,     "md5_128"      },
+#ifdef HAVE_CRYPTO_SHA256
+	{ IPMI_INTEGRITY_HMAC_SHA256_128, "sha256_128"      },
+#endif // HAVE_CRYPTO_SHA256
 	{ 0x00, NULL }
 };
 
diff -Nur ipmitool.sav/src/plugins/lanplus/lanplus.c ipmitool/src/plugins/lanplus/lanplus.c
--- ipmitool.sav/src/plugins/lanplus/lanplus.c	2010-07-27 18:36:56.000000000 +0200
+++ ipmitool/src/plugins/lanplus/lanplus.c	2011-05-04 13:42:13.145080000 +0200
@@ -158,9 +158,13 @@
 								  uint8_t * integrity_alg,
 								  uint8_t * crypt_alg)
 {
+#ifdef HAVE_CRYPTO_SHA256
+	if ((cipher_suite_id < 0) || (cipher_suite_id > 17))
+		return 1;
+#else
 	if ((cipher_suite_id < 0) || (cipher_suite_id > 14))
 		return 1;
-
+#endif // HAVE_CRYPTO_SHA256
 		/* See table 22-19 for the source of the statement */
 	switch (cipher_suite_id)
 	{
@@ -239,6 +243,26 @@
 		*integrity_alg = IPMI_INTEGRITY_MD5_128;
 		*crypt_alg     = IPMI_CRYPT_XRC4_40;
 		break;
+#ifdef HAVE_CRYPTO_SHA256
+#if 0
+	case 15: // Note: Cipher Suite ID not (yet) confirmed in IPMI Spec or Errata 4
+		*auth_alg      = IPMI_AUTH_RAKP_HMAC_SHA256;
+		*integrity_alg = IPMI_INTEGRITY_NONE;
+		*crypt_alg     = IPMI_CRYPT_NONE;
+		break;
+	case 16: // Note: Cipher Suite ID not (yet) confirmed in IPMI Spec or Errata 4
+		*auth_alg      = IPMI_AUTH_RAKP_HMAC_SHA256;
+		*integrity_alg = IPMI_INTEGRITY_HMAC_SHA256_128;
+		*crypt_alg     = IPMI_CRYPT_NONE;
+		break;
+#endif
+	case 17: // Note: Cipher Suite Id from DCMI 1.1 Spec
+		*auth_alg      = IPMI_AUTH_RAKP_HMAC_SHA256;
+		*integrity_alg = IPMI_INTEGRITY_HMAC_SHA256_128;
+		*crypt_alg     = IPMI_CRYPT_AES_CBC_128;
+		break;
+
+#endif // HAVE_CRYPTO_SHA256
 	}
 
 	return 0;
@@ -1016,14 +1040,30 @@
 
 	 case IPMI_AUTH_RAKP_HMAC_SHA1:
 		 /* We need to copy 20 bytes */
-		 for (i = 0; i < 20; ++i)
+		 for (i = 0; i < SHA_DIGEST_LENGTH; ++i)
 			 rsp->payload.rakp2_message.key_exchange_auth_code[i] =
 				 rsp->data[offset + 40 + i];
 		 break;
 
 	 case IPMI_AUTH_RAKP_HMAC_MD5:
-		lprintf(LOG_ERR, "read_rakp2_message: no support for "
-				"IPMI_AUTH_RAKP_HMAC_MD5");
+		 /* We need to copy 16 bytes */
+		 for (i = 0; i < MD5_DIGEST_LENGTH; ++i)
+			 rsp->payload.rakp2_message.key_exchange_auth_code[i] =
+				 rsp->data[offset + 40 + i];
+		 break;
+
+#ifdef HAVE_CRYPTO_SHA256
+	 case IPMI_AUTH_RAKP_HMAC_SHA256:
+		 /* We need to copy 32 bytes */
+		 for (i = 0; i < SHA256_DIGEST_LENGTH; ++i)
+			 rsp->payload.rakp2_message.key_exchange_auth_code[i] =
+				 rsp->data[offset + 40 + i];
+		 break;
+#endif // HAVE_CRYPTO_SHA256
+
+	 default:
+		 lprintf(LOG_ERR, "read_rakp2_message: no support "
+			 "for authentication algorithm 0x%x", auth_alg);
 		 assert(0);
 		 break;
 	 }
@@ -1082,12 +1122,28 @@
 
 	 case IPMI_AUTH_RAKP_HMAC_SHA1:
 		 /* We need to copy 12 bytes */
-		 for (i = 0; i < 12; ++i)
+		 for (i = 0; i < IPMI_SHA1_AUTHCODE_SIZE; ++i)
 			 rsp->payload.rakp4_message.integrity_check_value[i] =
 				 rsp->data[offset + 8 + i];
 		 break;
 
 	 case IPMI_AUTH_RAKP_HMAC_MD5:
+		 /* We need to copy 16 bytes */
+		 for (i = 0; i < IPMI_HMAC_MD5_AUTHCODE_SIZE; ++i)
+			 rsp->payload.rakp4_message.integrity_check_value[i] =
+				 rsp->data[offset + 8 + i];
+		 break;
+
+#ifdef HAVE_CRYPTO_SHA256
+	 case IPMI_AUTH_RAKP_HMAC_SHA256:
+		 /* We need to copy 16 bytes */
+		 for (i = 0; i < IPMI_HMAC_SHA256_AUTHCODE_SIZE; ++i)
+			 rsp->payload.rakp4_message.integrity_check_value[i] =
+				 rsp->data[offset + 8 + i];
+		 break;
+#endif // HAVE_CRYPTO_SHA256
+
+	 default:
 		 lprintf(LOG_ERR, "read_rakp4_message: no support "
 			 "for authentication algorithm 0x%x", auth_alg);
 		 assert(0);
@@ -1759,7 +1815,7 @@
 	if ((session->v2_data.session_state == LANPLUS_STATE_ACTIVE) &&
 		(session->v2_data.integrity_alg != IPMI_INTEGRITY_NONE))
 	{
-		uint32_t i, hmac_length, integrity_pad_size = 0, hmac_input_size;
+		uint32_t i, hmac_length, auth_length = 0, integrity_pad_size = 0, hmac_input_size;
 		uint8_t * hmac_output;
 		uint32_t start_of_session_trailer =
 			IPMI_LANPLUS_OFFSET_PAYLOAD +
@@ -1817,22 +1873,41 @@
 		/* Auth Code */
 		lanplus_HMAC(session->v2_data.integrity_alg,
 					 session->v2_data.k1,                /* key        */
-					 20,                                 /* key length */
+					 session->v2_data.k1_len,            /* key length */
 					 msg + IPMI_LANPLUS_OFFSET_AUTHTYPE, /* hmac input */
 					 hmac_input_size,
 					 hmac_output,
 					 &hmac_length);
 
-		assert(hmac_length == 20);
+		switch(session->v2_data.integrity_alg)
+		{
+		case IPMI_INTEGRITY_HMAC_SHA1_96: 
+			assert(hmac_length == SHA_DIGEST_LENGTH); 
+			auth_length = IPMI_SHA1_AUTHCODE_SIZE; 
+			break;
+		case IPMI_INTEGRITY_HMAC_MD5_128 : 
+			assert(hmac_length == MD5_DIGEST_LENGTH); 
+			auth_length = IPMI_HMAC_MD5_AUTHCODE_SIZE; 
+			break;
+#ifdef HAVE_CRYPTO_SHA256
+		case IPMI_INTEGRITY_HMAC_SHA256_128: 
+			assert(hmac_length == SHA256_DIGEST_LENGTH); 
+			auth_length = IPMI_HMAC_SHA256_AUTHCODE_SIZE; 
+			break;
+#endif // HAVE_CRYPTO_SHA256
+		default:
+			assert(0);
+			break;
+		}
 
 		if (verbose > 2)
-			printbuf(hmac_output, 12, "authcode output");
+			printbuf(hmac_output, auth_length, "authcode output");
 
 		/* Set session_trailer_length appropriately */
 		session_trailer_length =
 			integrity_pad_size +
 			2                  + /* pad length + next header */
-			12;                  /* Size of the authcode (we only use the first 12 bytes) */
+			auth_length;         /* Size of the authcode (we only use the first 12(SHA1) or 16(MD5/SHA256) bytes) */
 	}
 
 
@@ -3172,7 +3247,7 @@
 		else if (lanplus_generate_k2(session))
 		{
 			/* Error */
-			lprintf(LOG_INFO, "> Error generating K1 key");
+			lprintf(LOG_INFO, "> Error generating K2 key");
 			free(msg);
 			return 1;
 		}
@@ -3349,7 +3424,8 @@
 	session->sol_data.sequence_number = 1;
 	//session->sol_data.last_received_sequence_number = 0;
 	//session->sol_data.last_received_byte_count      = 0;
-	memset(session->v2_data.sik, 0, IPMI_SIK_BUFFER_SIZE);
+	memset(session->v2_data.sik, 0, sizeof(session->v2_data.sik));
+	session->v2_data.sik_len = 0;
 
 	/* Kg is set in ipmi_intf */
 	//memset(session->v2_data.kg,  0, IPMI_KG_BUFFER_SIZE);
diff -Nur ipmitool.sav/src/plugins/lanplus/lanplus_crypt.c ipmitool/src/plugins/lanplus/lanplus_crypt.c
--- ipmitool.sav/src/plugins/lanplus/lanplus_crypt.c	2007-08-29 22:17:52.000000000 +0200
+++ ipmitool/src/plugins/lanplus/lanplus_crypt.c	2011-05-04 14:21:22.315415000 +0200
@@ -74,7 +74,7 @@
 {
 	uint8_t       * buffer;
 	int           bufferLength, i;
-	uint8_t       mac[20];
+	uint8_t       mac[EVP_MAX_MD_SIZE];
 	uint32_t      macLength;
 
 	uint32_t SIDm_lsbf, SIDc_lsbf;
@@ -84,7 +84,12 @@
 		return 1;
 	
 	/* We don't yet support other algorithms */
-	assert(session->v2_data.auth_alg == IPMI_AUTH_RAKP_HMAC_SHA1);
+	assert((session->v2_data.auth_alg == IPMI_AUTH_RAKP_HMAC_SHA1)
+	   ||  (session->v2_data.auth_alg == IPMI_AUTH_RAKP_HMAC_MD5) 
+#ifdef HAVE_CRYPTO_SHA256
+	   ||  (session->v2_data.auth_alg == IPMI_AUTH_RAKP_HMAC_SHA256)
+#endif // HAVE_CRYPTO_SHA256
+	);
 	
 
 	bufferLength =
@@ -218,8 +223,9 @@
 {
 	uint8_t       * buffer;
 	int           bufferLength, i;
-	uint8_t       mac[20];
+	uint8_t       mac[EVP_MAX_MD_SIZE];
 	uint32_t      macLength;
+	uint32_t      cmpLength;
 	uint32_t      SIDc_lsbf;
 
 	if (ipmi_oem_active(intf, "intelplus")){
@@ -227,14 +233,20 @@
 		if (session->v2_data.integrity_alg == IPMI_INTEGRITY_NONE)
 			return 1;
 
-		/* We don't yet support other algorithms */
-		assert(session->v2_data.integrity_alg == IPMI_INTEGRITY_HMAC_SHA1_96);
+		/* (Old) Intel BMC doesn't support other algorithms */
+		assert((session->v2_data.integrity_alg == IPMI_INTEGRITY_HMAC_SHA1_96) ||
+		       (session->v2_data.integrity_alg == IPMI_INTEGRITY_HMAC_MD5_128));
 	} else {
 		if (session->v2_data.auth_alg == IPMI_AUTH_RAKP_NONE)
 			return 1;
 
 		/* We don't yet support other algorithms */
-		assert(session->v2_data.auth_alg == IPMI_AUTH_RAKP_HMAC_SHA1);
+		assert((session->v2_data.auth_alg == IPMI_AUTH_RAKP_HMAC_SHA1)
+		   ||  (session->v2_data.auth_alg == IPMI_AUTH_RAKP_HMAC_MD5)
+#ifdef HAVE_CRYPTO_SHA256
+		   ||  (session->v2_data.auth_alg == IPMI_AUTH_RAKP_HMAC_SHA256)
+#endif // HAVE_CRYPTO_SHA256
+		);
 	}
 
 	bufferLength =
@@ -284,7 +296,7 @@
 	if (verbose > 2)
 	{
 		printbuf((const uint8_t *)buffer, bufferLength, ">> rakp4 mac input buffer");
-		printbuf(session->v2_data.sik, 20l, ">> rakp4 mac key (sik)");
+		printbuf(session->v2_data.sik, session->v2_data.sik_len, ">> rakp4 mac key (sik)");
 	}
 
 
@@ -295,7 +307,7 @@
 	             ? session->v2_data.integrity_alg 
 	             : session->v2_data.auth_alg ,
 				 session->v2_data.sik,
-				 IPMI_SIK_BUFFER_SIZE,
+				 session->v2_data.sik_len,
 				 buffer,
 				 bufferLength,
 				 mac,
@@ -307,11 +319,51 @@
 		printbuf(mac,     macLength, ">> rakp4 mac as computed by the remote console");
 	}
 
+	if (ipmi_oem_active(intf, "intelplus")){
+		/* Intel BMC responds with the integrity Algorithm in RAKP4 */
+		switch(session->v2_data.integrity_alg)
+		{
+		case IPMI_INTEGRITY_HMAC_SHA1_96: 
+			assert(macLength == SHA_DIGEST_LENGTH); 
+			cmpLength = IPMI_SHA1_AUTHCODE_SIZE; 
+			break;
+		case IPMI_INTEGRITY_HMAC_MD5_128: 
+			assert(macLength == MD5_DIGEST_LENGTH); 
+			cmpLength = IPMI_HMAC_MD5_AUTHCODE_SIZE; 
+			break;
+		default: 
+			assert(0);
+			break;
+		}
 
+	} else {
+
+		/* We don't yet support other algorithms */
+		switch(session->v2_data.auth_alg)
+		{
+		case IPMI_AUTH_RAKP_HMAC_SHA1: 
+			assert(macLength == SHA_DIGEST_LENGTH); 
+			cmpLength = IPMI_SHA1_AUTHCODE_SIZE; 
+			break;
+		case IPMI_AUTH_RAKP_HMAC_MD5 : 
+			assert(macLength == MD5_DIGEST_LENGTH); 
+			cmpLength = IPMI_HMAC_MD5_AUTHCODE_SIZE; 
+			break;
+#ifdef HAVE_CRYPTO_SHA256
+		case IPMI_AUTH_RAKP_HMAC_SHA256: 
+			assert(macLength == SHA256_DIGEST_LENGTH); 
+			cmpLength = IPMI_HMAC_SHA256_AUTHCODE_SIZE; 
+			break;
+#endif // HAVE_CRYPTO_SHA256
+		default:
+			assert(0);
+			break;
+		}
+	}
 
 	free(buffer);
-	assert(macLength == 20);
-	return (memcmp(bmc_mac, mac, 12) == 0);
+	assert(macLength >= cmpLength);
+	return (memcmp(bmc_mac, mac, cmpLength) == 0);
 }
 
 
@@ -357,7 +409,12 @@
 	}
 
 	/* We don't yet support other algorithms */
-	assert(session->v2_data.auth_alg == IPMI_AUTH_RAKP_HMAC_SHA1);
+	assert((session->v2_data.auth_alg == IPMI_AUTH_RAKP_HMAC_SHA1)
+	   ||  (session->v2_data.auth_alg == IPMI_AUTH_RAKP_HMAC_MD5)
+#ifdef HAVE_CRYPTO_SHA256
+	   ||  (session->v2_data.auth_alg == IPMI_AUTH_RAKP_HMAC_SHA256)
+#endif // HAVE_CRYPTO_SHA256
+	);
 
 	input_buffer_length =
 		16 + /* Rc       */
@@ -465,13 +522,19 @@
 	uint32_t mac_length;
 	
 
-	memset(session->v2_data.sik, 0, IPMI_SIK_BUFFER_SIZE);
+	memset(session->v2_data.sik, 0, sizeof(session->v2_data.sik));
+	session->v2_data.sik_len = 0;
 
 	if (session->v2_data.auth_alg == IPMI_AUTH_RAKP_NONE)
 		return 0;
 
 	/* We don't yet support other algorithms */
-	assert(session->v2_data.auth_alg == IPMI_AUTH_RAKP_HMAC_SHA1);
+	assert((session->v2_data.auth_alg == IPMI_AUTH_RAKP_HMAC_SHA1)
+	   ||  (session->v2_data.auth_alg == IPMI_AUTH_RAKP_HMAC_MD5)
+#ifdef HAVE_CRYPTO_SHA256
+	   ||  (session->v2_data.auth_alg == IPMI_AUTH_RAKP_HMAC_SHA256)
+#endif // HAVE_CRYPTO_SHA256
+	);
 
 	input_buffer_length =
 		16 +  /* Rm       */
@@ -549,14 +612,24 @@
 				 &mac_length);
 
 	free(input_buffer);
-	assert(mac_length == 20);
+	switch(session->v2_data.auth_alg)
+	{
+	case IPMI_AUTH_RAKP_HMAC_SHA1  : assert(mac_length == SHA_DIGEST_LENGTH); break;
+	case IPMI_AUTH_RAKP_HMAC_MD5   : assert(mac_length == MD5_DIGEST_LENGTH); break;
+#ifdef HAVE_CRYPTO_SHA256
+	case IPMI_AUTH_RAKP_HMAC_SHA256: assert(mac_length == SHA256_DIGEST_LENGTH); break;
+#endif // HAVE_CRYPTO_SHA256
+	default                        : assert(0); break;
+	}
+	
+	session->v2_data.sik_len = mac_length;
 
 	/*
 	 * The key MAC generated is 20 bytes, but we will only be using the first
 	 * 12 for SHA1 96
 	 */
 	if (verbose >= 2)
-		printbuf(session->v2_data.sik, 20, "Generated session integrity key");
+		printbuf(session->v2_data.sik, session->v2_data.sik_len, "Generated session integrity key");
 
 	return 0;
 }
@@ -590,16 +663,25 @@
 	{
 		lanplus_HMAC(session->v2_data.auth_alg,
 					 session->v2_data.sik,
-					 IPMI_SIK_BUFFER_SIZE, /* SIK length */
+					 session->v2_data.sik_len,/* SIK length */
 					 CONST_1,
 					 20,
 					 session->v2_data.k1,
 					 &mac_length);
-		assert(mac_length == 20);
+		switch(session->v2_data.auth_alg)
+		{
+		case IPMI_AUTH_RAKP_HMAC_SHA1  : assert(mac_length == SHA_DIGEST_LENGTH); break;
+		case IPMI_AUTH_RAKP_HMAC_MD5   : assert(mac_length == MD5_DIGEST_LENGTH); break;
+#ifdef HAVE_CRYPTO_SHA256
+		case IPMI_AUTH_RAKP_HMAC_SHA256: assert(mac_length == SHA256_DIGEST_LENGTH); break;
+#endif // HAVE_CRYPTO_SHA256
+		default                        : assert(0); break;
+		}
+		session->v2_data.k1_len = mac_length;
 	}
 
 	if (verbose >= 2)
-		printbuf(session->v2_data.k1, 20, "Generated K1");
+		printbuf(session->v2_data.k1, session->v2_data.k1_len, "Generated K1");
 
 	return 0;
 }
@@ -633,16 +715,25 @@
 	{
 		lanplus_HMAC(session->v2_data.auth_alg,
 					 session->v2_data.sik,
-					 IPMI_SIK_BUFFER_SIZE, /* SIK length */
+					 session->v2_data.sik_len,/* SIK length */
 					 CONST_2,
 					 20,
 					 session->v2_data.k2,
 					 &mac_length);
-		assert(mac_length == 20);
+		switch(session->v2_data.auth_alg)
+		{
+		case IPMI_AUTH_RAKP_HMAC_SHA1  : assert(mac_length == SHA_DIGEST_LENGTH); break;
+		case IPMI_AUTH_RAKP_HMAC_MD5   : assert(mac_length == MD5_DIGEST_LENGTH); break;
+#ifdef HAVE_CRYPTO_SHA256
+		case IPMI_AUTH_RAKP_HMAC_SHA256: assert(mac_length == SHA256_DIGEST_LENGTH); break;
+#endif // HAVE_CRYPTO_SHA256
+		default                        : assert(0); break;
+		}
+		session->v2_data.k2_len = mac_length;
 	}
 
 	if (verbose >= 2)
-		printbuf(session->v2_data.k2, 20, "Generated K2");
+		printbuf(session->v2_data.k2, session->v2_data.k2_len, "Generated K2");
 
 	return 0;
 }
@@ -772,8 +863,9 @@
 								struct ipmi_session * session)
 {
 	uint8_t * bmc_authcode;
-	uint8_t   generated_authcode[IPMI_MAX_MAC_SIZE];
+	uint8_t   generated_authcode[EVP_MAX_MD_SIZE];
 	uint32_t    generated_authcode_length;
+	uint32_t    authcode_length;
 	
 
 	if ((rs->session.authtype != IPMI_SESSION_AUTHTYPE_RMCP_PLUS) ||
@@ -782,36 +874,43 @@
 		(session->v2_data.integrity_alg == IPMI_INTEGRITY_NONE))
 		return 1;
 	
-	/* We only support SHA1-96 now */
-	assert(session->v2_data.integrity_alg == IPMI_INTEGRITY_HMAC_SHA1_96);
+	switch(session->v2_data.integrity_alg)
+	{
+	case IPMI_INTEGRITY_HMAC_SHA1_96   : authcode_length = IPMI_SHA1_AUTHCODE_SIZE; break;
+	case IPMI_INTEGRITY_HMAC_MD5_128   : authcode_length = IPMI_HMAC_MD5_AUTHCODE_SIZE; break;
+#ifdef HAVE_CRYPTO_SHA256
+	case IPMI_INTEGRITY_HMAC_SHA256_128: authcode_length = IPMI_HMAC_SHA256_AUTHCODE_SIZE; break;
+#endif // HAVE_CRYPTO_SHA256
+	/* Unsupported */
+	default: assert(0); break;
+	}
 
 	/*
 	 * For SHA1-96, the authcode will be the last 12 bytes in the packet
 	 */
-	bmc_authcode = rs->data + (rs->data_len - IPMI_SHA1_AUTHCODE_SIZE);
+	bmc_authcode = rs->data + (rs->data_len - authcode_length);
 
 	lanplus_HMAC(session->v2_data.integrity_alg,
 				 session->v2_data.k1,
-				 IPMI_AUTHCODE_BUFFER_SIZE,
+				 session->v2_data.k1_len,
 				 rs->data + IPMI_LANPLUS_OFFSET_AUTHTYPE,
-				 rs->data_len - IPMI_LANPLUS_OFFSET_AUTHTYPE - IPMI_SHA1_AUTHCODE_SIZE,
+				 rs->data_len - IPMI_LANPLUS_OFFSET_AUTHTYPE - authcode_length,
 				 generated_authcode,
 				 &generated_authcode_length);
 
 	if (verbose > 3)
 	{
 		lprintf(LOG_DEBUG+2, "Validating authcode");
-		printbuf(session->v2_data.k1, 20, "K1");
+		printbuf(session->v2_data.k1, session->v2_data.k1_len, "K1");
 		printbuf(rs->data + IPMI_LANPLUS_OFFSET_AUTHTYPE,
-				 rs->data_len - IPMI_LANPLUS_OFFSET_AUTHTYPE - IPMI_SHA1_AUTHCODE_SIZE,
+				 rs->data_len - IPMI_LANPLUS_OFFSET_AUTHTYPE - authcode_length,
 				 "Authcode Input Data");
-		printbuf(generated_authcode, 12, "Generated authcode");
-		printbuf(bmc_authcode,       12, "Expected authcode");
+		printbuf(generated_authcode, generated_authcode_length, "Generated authcode");
+		printbuf(bmc_authcode,       authcode_length, "Expected authcode");
 	}
 
-	
-	assert(generated_authcode_length == 20);
-	return (memcmp(bmc_authcode, generated_authcode, 12) == 0);
+	assert(generated_authcode_length >= authcode_length);
+	return (memcmp(bmc_authcode, generated_authcode, authcode_length) == 0);
 }
 
 
diff -Nur ipmitool.sav/src/plugins/lanplus/lanplus_crypt.h ipmitool/src/plugins/lanplus/lanplus_crypt.h
--- ipmitool.sav/src/plugins/lanplus/lanplus_crypt.h	2006-03-19 22:54:44.000000000 +0100
+++ ipmitool/src/plugins/lanplus/lanplus_crypt.h	2011-05-04 10:24:09.131654000 +0200
@@ -35,6 +35,10 @@
 
 #include <ipmitool/ipmi_intf.h>
 
+#include <openssl/evp.h>
+#include <openssl/sha.h>
+#include <openssl/md5.h>
+
 /*
  * See the implementation file for documentation
  * ipmi_intf can be used for oem specific implementations 
diff -Nur ipmitool.sav/src/plugins/lanplus/lanplus_crypt_impl.c ipmitool/src/plugins/lanplus/lanplus_crypt_impl.c
--- ipmitool.sav/src/plugins/lanplus/lanplus_crypt_impl.c	2006-07-28 22:17:26.000000000 +0200
+++ ipmitool/src/plugins/lanplus/lanplus_crypt_impl.c	2011-05-04 10:28:22.401819000 +0200
@@ -99,7 +99,7 @@
 /*
  * lanplus_HMAC
  *
- * param mac specifies the algorithm to be used, currently only SHA1 is supported
+ * param mac specifies the algorithm to be used, currently SHA1/SHA256 and MD5 are supported
  * param key is the key used for HMAC generation
  * param key_len is the lenght of key
  * param d is the data to be MAC'd
@@ -123,6 +123,14 @@
 	if ((mac == IPMI_AUTH_RAKP_HMAC_SHA1) ||
 		(mac == IPMI_INTEGRITY_HMAC_SHA1_96))
 		evp_md = EVP_sha1();
+	else if ((mac == IPMI_AUTH_RAKP_HMAC_MD5) ||
+		     (mac == IPMI_INTEGRITY_HMAC_MD5_128))
+		evp_md = EVP_md5();
+#ifdef HAVE_CRYPTO_SHA256
+	else if ((mac == IPMI_AUTH_RAKP_HMAC_SHA256) ||
+		     (mac == IPMI_INTEGRITY_HMAC_SHA256_128))
+		evp_md = EVP_sha256();
+#endif // HAVE_CRYPTO_SHA256
 	else
 	{
 		lprintf(LOG_DEBUG, "Invalid mac type 0x%x in lanplus_HMAC\n", mac);
diff -Nur ipmitool.sav/src/plugins/lanplus/lanplus_dump.c ipmitool/src/plugins/lanplus/lanplus_dump.c
--- ipmitool.sav/src/plugins/lanplus/lanplus_dump.c	2006-03-19 19:59:40.000000000 +0100
+++ ipmitool/src/plugins/lanplus/lanplus_dump.c	2011-05-04 10:26:29.620508000 +0200
@@ -31,6 +31,7 @@
  */
 
 #include "lanplus.h"
+#include "lanplus_crypt.h"
 #include "lanplus_dump.h"
 
 extern const struct valstr ipmi_rakp_return_codes[];
@@ -127,16 +128,24 @@
 		break;
 	case IPMI_AUTH_RAKP_HMAC_SHA1:
 		printf("%s  Key exchange auth code [sha1] : 0x", DUMP_PREFIX_INCOMING);
-		for (i = 0; i < 20; ++i)
+		for (i = 0; i < SHA_DIGEST_LENGTH; ++i)
 			printf("%02x", rsp->payload.rakp2_message.key_exchange_auth_code[i]);
 		printf("\n");	
 		break;
 	case IPMI_AUTH_RAKP_HMAC_MD5:
 		printf("%s  Key exchange auth code [md5]   : 0x", DUMP_PREFIX_INCOMING);
-		for (i = 0; i < 16; ++i)
+		for (i = 0; i < MD5_DIGEST_LENGTH; ++i)
 			printf("%02x", rsp->payload.rakp2_message.key_exchange_auth_code[i]);
 		printf("\n");	
 		break;
+#ifdef HAVE_CRYPTO_SHA256
+	case IPMI_AUTH_RAKP_HMAC_SHA256:
+		printf("%s  Key exchange auth code [sha256]: 0x", DUMP_PREFIX_INCOMING);
+		for (i = 0; i < SHA256_DIGEST_LENGTH; ++i)
+			printf("%02x", rsp->payload.rakp2_message.key_exchange_auth_code[i]);
+		printf("\n");	
+		break;
+#endif // HAVE_CRYPTO_SHA256
 	default:
 		printf("%s  Key exchange auth code         : invalid", DUMP_PREFIX_INCOMING);
 	}
@@ -174,16 +183,24 @@
 		break;
 	case IPMI_AUTH_RAKP_HMAC_SHA1:
 		printf("%s  Key exchange auth code [sha1] : 0x", DUMP_PREFIX_INCOMING);
-		for (i = 0; i < 12; ++i)
+		for (i = 0; i < IPMI_SHA1_AUTHCODE_SIZE; ++i)
 			printf("%02x", rsp->payload.rakp4_message.integrity_check_value[i]);
 		printf("\n");	
 		break;
 	case IPMI_AUTH_RAKP_HMAC_MD5:
 		printf("%s  Key exchange auth code [md5]   : 0x", DUMP_PREFIX_INCOMING);
-		for (i = 0; i < 12; ++i)
+		for (i = 0; i < IPMI_HMAC_MD5_AUTHCODE_SIZE; ++i)
+			printf("%02x", rsp->payload.rakp4_message.integrity_check_value[i]);
+		printf("\n");	
+		break;
+#ifdef HAVE_CRYPTO_SHA256
+	case IPMI_AUTH_RAKP_HMAC_SHA256:
+		printf("%s  Key exchange auth code [sha256]: 0x", DUMP_PREFIX_INCOMING);
+		for (i = 0; i < IPMI_HMAC_SHA256_AUTHCODE_SIZE; ++i)
 			printf("%02x", rsp->payload.rakp4_message.integrity_check_value[i]);
 		printf("\n");	
 		break;
+#endif // HAVE_CRYPTO_SHA256
 	default:
 		printf("%s  Key exchange auth code         : invalid", DUMP_PREFIX_INCOMING);
 	}
diff -Nur ipmitool.sav/src/plugins/lanplus/lanplus.h ipmitool/src/plugins/lanplus/lanplus.h
--- ipmitool.sav/src/plugins/lanplus/lanplus.h	2007-08-29 22:17:52.000000000 +0200
+++ ipmitool/src/plugins/lanplus/lanplus.h	2011-05-04 10:23:52.555090000 +0200
@@ -96,12 +96,15 @@
 #define IPMI_MAX_CONF_HEADER_SIZE   0x20
 #define IPMI_MAX_PAYLOAD_SIZE       0xFFFF /* Includes confidentiality header/trailer */
 #define IPMI_MAX_CONF_TRAILER_SIZE  0x20
-#define IPMI_MAX_INTEGRITY_PAD_SIZE 0x20
-#define IPMI_MAX_AUTH_CODE_SIZE     0x20
+#define IPMI_MAX_INTEGRITY_PAD_SIZE EVP_MAX_MD_SIZE
+#define IPMI_MAX_AUTH_CODE_SIZE     EVP_MAX_MD_SIZE // In RAKP2/RAKP3
 
 #define IPMI_REQUEST_MESSAGE_SIZE   0x07
-#define IPMI_MAX_MAC_SIZE           0x14 /* The largest mac we ever expect to generate */
-#define IPMI_SHA1_AUTHCODE_SIZE     0x0C
+#define IPMI_MAX_MAC_SIZE           EVP_MAX_MD_SIZE /* The largest mac we ever expect to generate */
+#define IPMI_SHA1_AUTHCODE_SIZE          12 
+#define IPMI_HMAC_MD5_AUTHCODE_SIZE      16
+#define IPMI_MD5_AUTHCODE_SIZE           16
+#define IPMI_HMAC_SHA256_AUTHCODE_SIZE   16
 
 /*
  *This is accurate, as long as we're only passing 1 auth algorithm,
@@ -109,7 +112,7 @@
  */
 #define IPMI_OPEN_SESSION_REQUEST_SIZE 32
 #define IPMI_RAKP1_MESSAGE_SIZE        44
-#define IPMI_RAKP3_MESSAGE_MAX_SIZE    28
+#define IPMI_RAKP3_MESSAGE_MAX_SIZE    (8+EVP_MAX_MD_SIZE)
 
 #define IPMI_MAX_USER_NAME_LENGTH      16
 
