diff options
Diffstat (limited to 'src/plugins/lanplus')
| -rw-r--r-- | src/plugins/lanplus/lanplus.c | 126 | ||||
| -rw-r--r-- | src/plugins/lanplus/lanplus.h | 18 | ||||
| -rw-r--r-- | src/plugins/lanplus/lanplus_crypt.c | 196 | ||||
| -rw-r--r-- | src/plugins/lanplus/lanplus_crypt_impl.c | 11 | ||||
| -rw-r--r-- | src/plugins/lanplus/lanplus_dump.c | 39 | 
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);  	} | 
