summaryrefslogtreecommitdiff
path: root/src/plugins/lanplus/lanplus_crypt.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/lanplus/lanplus_crypt.c')
-rw-r--r--src/plugins/lanplus/lanplus_crypt.c196
1 files changed, 161 insertions, 35 deletions
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);
}