summaryrefslogtreecommitdiff
path: root/src/plugins/lanplus
diff options
context:
space:
mode:
authorJörg Frings-Fürst <debian@jff-webhosting.net>2016-10-09 09:19:55 +0200
committerJörg Frings-Fürst <debian@jff-webhosting.net>2016-10-09 09:19:55 +0200
commit7ddeb3781f3d79ef1ae5a765a66f6cdd1ec113ef (patch)
tree3546836f27de4168559a62d8022626dfb101a133 /src/plugins/lanplus
parent5bac665e38a15e6725f9ec17c7f7e80a0506aa08 (diff)
parent82ac6c87ce0b0af2fb8de25d70442fec406bb742 (diff)
Merge tag 'upstream/1.8.18'
Upstream version 1.8.18
Diffstat (limited to 'src/plugins/lanplus')
-rw-r--r--src/plugins/lanplus/lanplus.c126
-rw-r--r--src/plugins/lanplus/lanplus.h18
-rw-r--r--src/plugins/lanplus/lanplus_crypt.c196
-rw-r--r--src/plugins/lanplus/lanplus_crypt_impl.c11
-rw-r--r--src/plugins/lanplus/lanplus_dump.c39
5 files changed, 323 insertions, 67 deletions
diff --git a/src/plugins/lanplus/lanplus.c b/src/plugins/lanplus/lanplus.c
index 2a89a14..a0e388c 100644
--- a/src/plugins/lanplus/lanplus.c
+++ b/src/plugins/lanplus/lanplus.c
@@ -169,9 +169,14 @@ int lanplus_get_requested_ciphers(int cipher_suite_id,
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)
{
@@ -250,6 +255,23 @@ int lanplus_get_requested_ciphers(int cipher_suite_id,
*integrity_alg = IPMI_INTEGRITY_MD5_128;
*crypt_alg = IPMI_CRYPT_XRC4_40;
break;
+#ifdef HAVE_CRYPTO_SHA256
+ case 15:
+ *auth_alg = IPMI_AUTH_RAKP_HMAC_SHA256;
+ *integrity_alg = IPMI_INTEGRITY_NONE;
+ *crypt_alg = IPMI_CRYPT_NONE;
+ break;
+ case 16:
+ *auth_alg = IPMI_AUTH_RAKP_HMAC_SHA256;
+ *integrity_alg = IPMI_INTEGRITY_HMAC_SHA256_128;
+ *crypt_alg = IPMI_CRYPT_NONE;
+ break;
+ case 17:
+ *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;
@@ -1022,15 +1044,34 @@ read_rakp2_message(
break;
case IPMI_AUTH_RAKP_HMAC_SHA1:
- /* We need to copy 20 bytes */
- for (i = 0; i < 20; ++i)
- rsp->payload.rakp2_message.key_exchange_auth_code[i] =
- rsp->data[offset + 40 + i];
- break;
+ /* We need to copy 20 bytes */
+ for (i = 0; i < IPMI_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 < IPMI_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 < IPMI_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;
}
@@ -1088,13 +1129,32 @@ read_rakp4_message(
break;
case IPMI_AUTH_RAKP_HMAC_SHA1:
- /* We need to copy 12 bytes */
- for (i = 0; i < 12; ++i)
- rsp->payload.rakp4_message.integrity_check_value[i] =
- rsp->data[offset + 8 + i];
- break;
+ /* We need to copy 12 bytes */
+ 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);
@@ -1760,7 +1820,11 @@ ipmi_lanplus_build_v2x_msg(
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;
+ uint32_t hmac_length;
+ uint32_t auth_length = 0;
+ uint32_t integrity_pad_size = 0;
+ uint32_t hmac_input_size;
uint8_t * hmac_output;
uint32_t start_of_session_trailer =
IPMI_LANPLUS_OFFSET_PAYLOAD +
@@ -1818,22 +1882,43 @@ ipmi_lanplus_build_v2x_msg(
/* 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 == IPMI_SHA_DIGEST_LENGTH);
+ auth_length = IPMI_SHA1_AUTHCODE_SIZE;
+ break;
+ case IPMI_INTEGRITY_HMAC_MD5_128 :
+ assert(hmac_length == IPMI_MD5_DIGEST_LENGTH);
+ auth_length = IPMI_HMAC_MD5_AUTHCODE_SIZE;
+ break;
+#ifdef HAVE_CRYPTO_SHA256
+ case IPMI_INTEGRITY_HMAC_SHA256_128:
+ assert(hmac_length == IPMI_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.
+ */
}
@@ -2284,6 +2369,10 @@ ipmi_lanplus_send_payload(
rsp = ipmi_lanplus_recv_sol(intf); /* Grab the next packet */
+ if (!is_sol_packet(rsp)) {
+ break;
+ }
+
if (sol_response_acks_packet(rsp, payload))
break;
@@ -2296,6 +2385,7 @@ ipmi_lanplus_send_payload(
intf->session->sol_data.sol_input_handler(rsp);
/* In order to avoid duplicate output, just set data_len to 0 */
rsp->data_len = 0;
+ break;
}
}
diff --git a/src/plugins/lanplus/lanplus.h b/src/plugins/lanplus/lanplus.h
index 4b6ae1e..d967462 100644
--- a/src/plugins/lanplus/lanplus.h
+++ b/src/plugins/lanplus/lanplus.h
@@ -96,12 +96,20 @@
#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 IPMI_MAX_MD_SIZE
+#define IPMI_MAX_AUTH_CODE_SIZE IPMI_MAX_MD_SIZE
#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 IPMI_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
+
+#define IPMI_SHA_DIGEST_LENGTH 20
+#define IPMI_MD5_DIGEST_LENGTH 16
+#define IPMI_SHA256_DIGEST_LENGTH 32
/*
*This is accurate, as long as we're only passing 1 auth algorithm,
@@ -109,7 +117,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 + IPMI_MAX_MD_SIZE)
#define IPMI_MAX_USER_NAME_LENGTH 16
diff --git a/src/plugins/lanplus/lanplus_crypt.c b/src/plugins/lanplus/lanplus_crypt.c
index 1cdd050..cb963f4 100644
--- a/src/plugins/lanplus/lanplus_crypt.c
+++ b/src/plugins/lanplus/lanplus_crypt.c
@@ -74,7 +74,7 @@ lanplus_rakp2_hmac_matches(const struct ipmi_session * session,
{
uint8_t * buffer;
int bufferLength, i;
- uint8_t mac[20];
+ uint8_t mac[IPMI_MAX_MD_SIZE];
uint32_t macLength;
uint32_t SIDm_lsbf, SIDc_lsbf;
@@ -84,7 +84,12 @@ lanplus_rakp2_hmac_matches(const struct ipmi_session * session,
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 =
@@ -228,8 +233,9 @@ lanplus_rakp4_hmac_matches(const struct ipmi_session * session,
{
uint8_t * buffer;
int bufferLength, i;
- uint8_t mac[20];
+ uint8_t mac[IPMI_MAX_MD_SIZE];
uint32_t macLength;
+ uint32_t cmpLength;
uint32_t SIDc_lsbf;
if (ipmi_oem_active(intf, "intelplus")){
@@ -238,13 +244,19 @@ lanplus_rakp4_hmac_matches(const struct ipmi_session * session,
return 1;
/* We don't yet support other algorithms */
- assert(session->v2_data.integrity_alg == IPMI_INTEGRITY_HMAC_SHA1_96);
+ 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 =
@@ -294,7 +306,8 @@ lanplus_rakp4_hmac_matches(const struct ipmi_session * session,
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)");
}
@@ -305,7 +318,7 @@ lanplus_rakp4_hmac_matches(const struct ipmi_session * session,
? 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,
@@ -317,12 +330,48 @@ lanplus_rakp4_hmac_matches(const struct ipmi_session * session,
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 == IPMI_SHA_DIGEST_LENGTH);
+ cmpLength = IPMI_SHA1_AUTHCODE_SIZE;
+ break;
+ case IPMI_INTEGRITY_HMAC_MD5_128:
+ assert(macLength == IPMI_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 == IPMI_SHA_DIGEST_LENGTH);
+ cmpLength = IPMI_SHA1_AUTHCODE_SIZE;
+ break;
+ case IPMI_AUTH_RAKP_HMAC_MD5:
+ assert(macLength == IPMI_MD5_DIGEST_LENGTH);
+ cmpLength = IPMI_HMAC_MD5_AUTHCODE_SIZE;
+ break;
+#ifdef HAVE_CRYPTO_SHA256
+ case IPMI_AUTH_RAKP_HMAC_SHA256:
+ assert(macLength == IPMI_SHA256_DIGEST_LENGTH);
+ cmpLength = IPMI_HMAC_SHA256_AUTHCODE_SIZE;
+ break;
+#endif /* HAVE_CRYPTO_SHA256 */
+ default:
+ assert(0);
+ break;
+ }
+ }
free(buffer);
buffer = NULL;
- assert(macLength == 20);
- return (memcmp(bmc_mac, mac, 12) == 0);
+ assert(macLength >= cmpLength);
+ return (memcmp(bmc_mac, mac, cmpLength) == 0);
}
@@ -368,7 +417,12 @@ lanplus_generate_rakp3_authcode(uint8_t * output_buffer,
}
/* 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 */
@@ -478,13 +532,19 @@ lanplus_generate_sik(struct ipmi_session * session, struct ipmi_intf * intf)
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 */
@@ -572,15 +632,33 @@ lanplus_generate_sik(struct ipmi_session * session, struct ipmi_intf * intf)
free(input_buffer);
input_buffer = NULL;
- assert(mac_length == 20);
+ switch (session->v2_data.auth_alg) {
+ case IPMI_AUTH_RAKP_HMAC_SHA1:
+ assert(mac_length == IPMI_SHA_DIGEST_LENGTH);
+ break;
+ case IPMI_AUTH_RAKP_HMAC_MD5:
+ assert(mac_length == IPMI_MD5_DIGEST_LENGTH);
+ break;
+#ifdef HAVE_CRYPTO_SHA256
+ case IPMI_AUTH_RAKP_HMAC_SHA256:
+ assert(mac_length == IPMI_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");
-
+ if (verbose >= 2) {
+ printbuf(session->v2_data.sik, session->v2_data.sik_len,
+ "Generated session integrity key");
+ }
return 0;
}
@@ -614,16 +692,32 @@ lanplus_generate_k1(struct ipmi_session * session)
{
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 == IPMI_SHA_DIGEST_LENGTH);
+ break;
+ case IPMI_AUTH_RAKP_HMAC_MD5:
+ assert(mac_length == IPMI_MD5_DIGEST_LENGTH);
+ break;
+#ifdef HAVE_CRYPTO_SHA256
+ case IPMI_AUTH_RAKP_HMAC_SHA256:
+ assert(mac_length == IPMI_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;
}
@@ -658,16 +752,32 @@ lanplus_generate_k2(struct ipmi_session * session)
{
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 == IPMI_SHA_DIGEST_LENGTH);
+ break;
+ case IPMI_AUTH_RAKP_HMAC_MD5:
+ assert(mac_length == IPMI_MD5_DIGEST_LENGTH);
+ break;
+#ifdef HAVE_CRYPTO_SHA256
+ case IPMI_AUTH_RAKP_HMAC_SHA256:
+ assert(mac_length == IPMI_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;
}
@@ -803,6 +913,7 @@ lanplus_has_valid_auth_code(struct ipmi_rs * rs, struct ipmi_session * session)
uint8_t * bmc_authcode;
uint8_t generated_authcode[IPMI_MAX_MAC_SIZE];
uint32_t generated_authcode_length;
+ uint32_t authcode_length;
if ((rs->session.authtype != IPMI_SESSION_AUTHTYPE_RMCP_PLUS) ||
@@ -811,36 +922,51 @@ lanplus_has_valid_auth_code(struct ipmi_rs * rs, struct ipmi_session * session)
(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
+ * For SHA256-128 or MD5-128, the authcode will be the last 16 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 --git a/src/plugins/lanplus/lanplus_crypt_impl.c b/src/plugins/lanplus/lanplus_crypt_impl.c
index cde6c54..d5fac37 100644
--- a/src/plugins/lanplus/lanplus_crypt_impl.c
+++ b/src/plugins/lanplus/lanplus_crypt_impl.c
@@ -99,7 +99,8 @@ lanplus_rand(uint8_t * buffer, uint32_t num_bytes)
/*
* 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 +124,14 @@ lanplus_HMAC(uint8_t mac,
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 --git a/src/plugins/lanplus/lanplus_dump.c b/src/plugins/lanplus/lanplus_dump.c
index 8d52fab..bbfc1b0 100644
--- a/src/plugins/lanplus/lanplus_dump.c
+++ b/src/plugins/lanplus/lanplus_dump.c
@@ -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,27 @@ void lanplus_dump_rakp2_message(const struct ipmi_rs * rsp, uint8_t auth_alg)
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 < IPMI_SHA_DIGEST_LENGTH; ++i) {
printf("%02x", rsp->payload.rakp2_message.key_exchange_auth_code[i]);
- printf("\n");
+ }
+ 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 < IPMI_MD5_DIGEST_LENGTH; ++i) {
printf("%02x", rsp->payload.rakp2_message.key_exchange_auth_code[i]);
- printf("\n");
+ }
+ 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_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 +186,27 @@ void lanplus_dump_rakp4_message(const struct ipmi_rs * rsp, uint8_t auth_alg)
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");
+ }
+ 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");
+ }
+ printf("\n");
break;
+#endif /* HAVE_CRYPTO_SHA256 */
default:
printf("%s Key exchange auth code : invalid", DUMP_PREFIX_INCOMING);
}