Index: libfreeipmi/include/freeipmi/interface/ipmi-rmcpplus-interface.h =================================================================== --- libfreeipmi/include/freeipmi/interface/ipmi-rmcpplus-interface.h (revision 7200) +++ libfreeipmi/include/freeipmi/interface/ipmi-rmcpplus-interface.h (working copy) @@ -84,7 +84,7 @@ #define IPMI_AUTHENTICATION_ALGORITHM_RAKP_NONE 0x00 #define IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_SHA1 0x01 #define IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_MD5 0x02 -#define IPMI_AUTHENTICATION_ALGOIRTHM_RAKP_HMAC_SHA256 0x03 +#define IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_SHA256 0x03 /* C0h - FFh - OEM */ /* all other reserved */ @@ -92,12 +92,13 @@ (((__algorithm) == IPMI_AUTHENTICATION_ALGORITHM_RAKP_NONE \ || (__algorithm) == IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_SHA1 \ || (__algorithm) == IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_MD5 \ - || (__algorithm) == IPMI_AUTHENTICATION_ALGOIRTHM_RAKP_HMAC_SHA256) ? 1 : 0) + || (__algorithm) == IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_SHA256) ? 1 : 0) #define IPMI_AUTHENTICATION_ALGORITHM_SUPPORTED(__algorithm) \ (((__algorithm) == IPMI_AUTHENTICATION_ALGORITHM_RAKP_NONE \ || (__algorithm) == IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_SHA1 \ - || (__algorithm) == IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_MD5) ? 1 : 0) + || (__algorithm) == IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_MD5 \ + || (__algorithm) == IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_SHA256) ? 1 : 0) /**************************************** * IPMI 2.0 Integrity Algorithm Numbers * @@ -110,6 +111,7 @@ #define IPMI_INTEGRITY_ALGORITHM_HMAC_SHA256_128 0x04 /* C0h - FFh - OEM */ /* all other reserved */ + #define IPMI_INTEGRITY_ALGORITHM_VALID(__algorithm) \ (((__algorithm) == IPMI_INTEGRITY_ALGORITHM_NONE \ || (__algorithm) == IPMI_INTEGRITY_ALGORITHM_HMAC_SHA1_96 \ @@ -121,7 +123,8 @@ (((__algorithm) == IPMI_INTEGRITY_ALGORITHM_NONE \ || (__algorithm) == IPMI_INTEGRITY_ALGORITHM_HMAC_SHA1_96 \ || (__algorithm) == IPMI_INTEGRITY_ALGORITHM_HMAC_MD5_128 \ - || (__algorithm) == IPMI_INTEGRITY_ALGORITHM_MD5_128) ? 1 : 0) + || (__algorithm) == IPMI_INTEGRITY_ALGORITHM_MD5_128 \ + || (__algorithm) == IPMI_INTEGRITY_ALGORITHM_HMAC_SHA256_128) ? 1 : 0) /********************************************** * IPMI 2.0 Confidentiality Algorithm Numbers * @@ -178,14 +181,18 @@ #define IPMI_HMAC_MD5_DIGEST_LENGTH 16 #define IPMI_MD5_DIGEST_LENGTH 16 #define IPMI_HMAC_SHA1_96_DIGEST_LENGTH 12 +#define IPMI_HMAC_SHA256_DIGEST_LENGTH 32 #define IPMI_HMAC_SHA1_96_AUTHENTICATION_CODE_LENGTH 12 #define IPMI_HMAC_MD5_128_AUTHENTICATION_CODE_LENGTH 16 #define IPMI_MD5_128_AUTHENTICATION_CODE_LENGTH 16 +#define IPMI_HMAC_SHA256_128_AUTHENTICATION_CODE_LENGTH 16 /* Refer to table 22-19 */ +/* XXX - Errata 4 defines SHA256 but not cipher suite IDs */ +/* Cipher Suite 17 confirmed via DCMI 1.1 specification */ #define IPMI_CIPHER_SUITE_ID_MIN 0 -#define IPMI_CIPHER_SUITE_ID_MAX 14 +#define IPMI_CIPHER_SUITE_ID_MAX 17 /* * fill* functions return 0 on success, -1 on error. Index: libfreeipmi/include/freeipmi/util/ipmi-cipher-suite-util.h =================================================================== --- libfreeipmi/include/freeipmi/util/ipmi-cipher-suite-util.h (revision 7200) +++ libfreeipmi/include/freeipmi/util/ipmi-cipher-suite-util.h (working copy) @@ -27,63 +27,90 @@ #include #define IPMI_CIPHER_SUITE_COMBINATION_VALID(__a, __i, __c) \ + /* Cipher Suite 0 */ \ ((((__a) == IPMI_AUTHENTICATION_ALGORITHM_RAKP_NONE \ && (__i) == IPMI_INTEGRITY_ALGORITHM_NONE \ && (__c) == IPMI_CONFIDENTIALITY_ALGORITHM_NONE) \ + /* Cipher Suite 1 */ \ || ((__a) == IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_SHA1 \ && ((__i) == IPMI_INTEGRITY_ALGORITHM_NONE \ && (__c) == IPMI_CONFIDENTIALITY_ALGORITHM_NONE)) \ + /* Cipher Suite 2-5 */ \ || ((__a) == IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_SHA1 \ && ((__i) == IPMI_INTEGRITY_ALGORITHM_HMAC_SHA1_96 \ && ((__c) == IPMI_CONFIDENTIALITY_ALGORITHM_NONE \ || (__c) == IPMI_CONFIDENTIALITY_ALGORITHM_AES_CBC_128 \ || (__c) == IPMI_CONFIDENTIALITY_ALGORITHM_XRC4_128 \ || (__c) == IPMI_CONFIDENTIALITY_ALGORITHM_XRC4_40))) \ + /* Cipher Suite 6 */ \ || ((__a) == IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_MD5 \ && ((__i) == IPMI_INTEGRITY_ALGORITHM_NONE \ && (__c) == IPMI_CONFIDENTIALITY_ALGORITHM_NONE)) \ + /* Cipher Suite 7-10 */ \ || ((__a) == IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_MD5 \ && ((__i) == IPMI_INTEGRITY_ALGORITHM_HMAC_MD5_128 \ && ((__c) == IPMI_CONFIDENTIALITY_ALGORITHM_NONE \ || (__c) == IPMI_CONFIDENTIALITY_ALGORITHM_AES_CBC_128 \ || (__c) == IPMI_CONFIDENTIALITY_ALGORITHM_XRC4_128 \ || (__c) == IPMI_CONFIDENTIALITY_ALGORITHM_XRC4_40))) \ + /* Cipher Suite 11-14 */ \ || ((__a) == IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_MD5 \ && ((__i) == IPMI_INTEGRITY_ALGORITHM_MD5_128 \ && ((__c) == IPMI_CONFIDENTIALITY_ALGORITHM_NONE \ || (__c) == IPMI_CONFIDENTIALITY_ALGORITHM_AES_CBC_128 \ || (__c) == IPMI_CONFIDENTIALITY_ALGORITHM_XRC4_128 \ - || (__c) == IPMI_CONFIDENTIALITY_ALGORITHM_XRC4_40)))) ? 1 : 0) + || (__c) == IPMI_CONFIDENTIALITY_ALGORITHM_XRC4_40))) \ + /* XXX: Errata 4 defines SHA256 but not cipher suite IDs */ \ + /* Cipher Suite 17 confirmed via DCMI 1.1 specification */ \ + /* Cipher Suite 15-19 */ \ + || ((__a) == IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_SHA256 \ + && ((__i) == IPMI_INTEGRITY_ALGORITHM_HMAC_SHA256_128 \ + && ((__c) == IPMI_CONFIDENTIALITY_ALGORITHM_AES_CBC_128))) ) ? 1 : 0) #define IPMI_CIPHER_SUITE_COMBINATION_SUPPORTED(__a, __i, __c) \ + /* Cipher Suite 0 */ \ ((((__a) == IPMI_AUTHENTICATION_ALGORITHM_RAKP_NONE \ && (__i) == IPMI_INTEGRITY_ALGORITHM_NONE \ && (__c) == IPMI_CONFIDENTIALITY_ALGORITHM_NONE) \ + /* Cipher Suite 1 */ \ || ((__a) == IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_SHA1 \ && ((__i) == IPMI_INTEGRITY_ALGORITHM_NONE \ && (__c) == IPMI_CONFIDENTIALITY_ALGORITHM_NONE)) \ + /* Cipher Suite 2-3 */ \ || ((__a) == IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_SHA1 \ && ((__i) == IPMI_INTEGRITY_ALGORITHM_HMAC_SHA1_96 \ && ((__c) == IPMI_CONFIDENTIALITY_ALGORITHM_NONE \ || (__c) == IPMI_CONFIDENTIALITY_ALGORITHM_AES_CBC_128))) \ + /* Cipher Suite 6 */ \ || ((__a) == IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_MD5 \ && ((__i) == IPMI_INTEGRITY_ALGORITHM_NONE \ && (__c) == IPMI_CONFIDENTIALITY_ALGORITHM_NONE)) \ + /* Cipher Suite 7-8 */ \ || ((__a) == IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_MD5 \ && ((__i) == IPMI_INTEGRITY_ALGORITHM_HMAC_MD5_128 \ && ((__c) == IPMI_CONFIDENTIALITY_ALGORITHM_NONE \ || (__c) == IPMI_CONFIDENTIALITY_ALGORITHM_AES_CBC_128))) \ + /* Cipher Suite 11-12 */ \ || ((__a) == IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_MD5 \ && ((__i) == IPMI_INTEGRITY_ALGORITHM_MD5_128 \ && ((__c) == IPMI_CONFIDENTIALITY_ALGORITHM_NONE \ - || (__c) == IPMI_CONFIDENTIALITY_ALGORITHM_AES_CBC_128)))) ? 1 : 0) + || (__c) == IPMI_CONFIDENTIALITY_ALGORITHM_AES_CBC_128))) \ + /* XXX: Errata 4 defines SHA256 but not cipher suite IDs */ \ + /* Cipher Suite 17 confirmed via DCMI 1.1 specification */ \ + /* Cipher Suite 17 */ \ + || ((__a) == IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_SHA256 \ + && ((__i) == IPMI_INTEGRITY_ALGORITHM_HMAC_SHA256_128 \ + && ((__c) == IPMI_CONFIDENTIALITY_ALGORITHM_AES_CBC_128)))) ? 1 : 0) +/* XXX: Errata 4 defines SHA256 but not cipher suite IDs */ +/* Cipher Suite 17 confirmed via DCMI 1.1 specification */ /* To avoid gcc warnings, add +1 in comparison */ /* achu: no macros here, cipher suite ids are numbers */ #define IPMI_CIPHER_SUITE_ID_SUPPORTED(__id) \ ((((__id + 1) >= (0 + 1) && (__id) <= 3) \ || ((__id) >= 6 && (__id) <= 8) \ - || ((__id) >= 11 && (__id) <= 12)) ? 1 : 0) + || ((__id) >= 11 && (__id) <= 12) \ + || ((__id) == 17)) ? 1 : 0) int ipmi_cipher_suite_id_to_algorithms (uint8_t cipher_suite_id, uint8_t *authentication_algorithm, Index: libfreeipmi/src/libcommon/ipmi-crypt.h =================================================================== --- libfreeipmi/src/libcommon/ipmi-crypt.h (revision 7200) +++ libfreeipmi/src/libcommon/ipmi-crypt.h (working copy) @@ -23,10 +23,12 @@ #define IPMI_CRYPT_HASH_SHA1 0x00 #define IPMI_CRYPT_HASH_MD5 0x01 +#define IPMI_CRYPT_HASH_SHA256 0x02 #define IPMI_CRYPT_HASH_ALGORITHM_VALID(__hash_algorithm) \ (((__hash_algorithm) == IPMI_CRYPT_HASH_SHA1 \ - || (__hash_algorithm) == IPMI_CRYPT_HASH_MD5) ? 1 : 0) + || (__hash_algorithm) == IPMI_CRYPT_HASH_MD5 \ + || (__hash_algorithm) == IPMI_CRYPT_HASH_SHA256) ? 1 : 0) #define IPMI_CRYPT_HASH_FLAGS_HMAC 0x01 Index: libfreeipmi/src/libcommon/ipmi-crypt.c =================================================================== --- libfreeipmi/src/libcommon/ipmi-crypt.c (revision 7200) +++ libfreeipmi/src/libcommon/ipmi-crypt.c (working copy) @@ -131,6 +131,8 @@ if (hash_algorithm == IPMI_CRYPT_HASH_SHA1) gcry_md_algorithm = GCRY_MD_SHA1; + else if (hash_algorithm == IPMI_CRYPT_HASH_SHA256) + gcry_md_algorithm = GCRY_MD_SHA256; else gcry_md_algorithm = GCRY_MD_MD5; @@ -221,6 +223,8 @@ if (hash_algorithm == IPMI_CRYPT_HASH_SHA1) gcry_md_algorithm = GCRY_MD_SHA1; + else if (hash_algorithm == IPMI_CRYPT_HASH_SHA256) + gcry_md_algorithm = GCRY_MD_SHA256; else gcry_md_algorithm = GCRY_MD_MD5; Index: libfreeipmi/src/debug/ipmi-debug-rmcpplus.c =================================================================== --- libfreeipmi/src/debug/ipmi-debug-rmcpplus.c (revision 7200) +++ libfreeipmi/src/debug/ipmi-debug-rmcpplus.c (working copy) @@ -1028,6 +1028,8 @@ authentication_code_len = IPMI_HMAC_MD5_128_AUTHENTICATION_CODE_LENGTH; else if (integrity_algorithm == IPMI_INTEGRITY_ALGORITHM_MD5_128) authentication_code_len = IPMI_MD5_128_AUTHENTICATION_CODE_LENGTH; + else if (integrity_algorithm == IPMI_INTEGRITY_ALGORITHM_HMAC_SHA256_128) + authentication_code_len = IPMI_HMAC_SHA256_128_AUTHENTICATION_CODE_LENGTH; else authentication_code_len = 0; /* just in case IPMI implementation is bogus */ Index: libfreeipmi/src/interface/ipmi-rmcpplus-interface.c =================================================================== --- libfreeipmi/src/interface/ipmi-rmcpplus-interface.c (revision 7200) +++ libfreeipmi/src/interface/ipmi-rmcpplus-interface.c (working copy) @@ -1029,7 +1029,8 @@ assert ((integrity_algorithm == IPMI_INTEGRITY_ALGORITHM_NONE || integrity_algorithm == IPMI_INTEGRITY_ALGORITHM_HMAC_SHA1_96 || integrity_algorithm == IPMI_INTEGRITY_ALGORITHM_HMAC_MD5_128 - || integrity_algorithm == IPMI_INTEGRITY_ALGORITHM_MD5_128)); + || integrity_algorithm == IPMI_INTEGRITY_ALGORITHM_MD5_128 + || integrity_algorithm == IPMI_INTEGRITY_ALGORITHM_HMAC_SHA256_128)); if (integrity_algorithm == IPMI_INTEGRITY_ALGORITHM_NONE) authentication_code_len = 0; @@ -1037,8 +1038,10 @@ authentication_code_len = IPMI_HMAC_SHA1_96_AUTHENTICATION_CODE_LENGTH; else if (integrity_algorithm == IPMI_INTEGRITY_ALGORITHM_HMAC_MD5_128) authentication_code_len = IPMI_HMAC_MD5_128_AUTHENTICATION_CODE_LENGTH; - else /* IPMI_INTEGRITY_ALGORITHM_MD5_128 */ + else if (integrity_algorithm == IPMI_INTEGRITY_ALGORITHM_MD5_128) authentication_code_len = IPMI_MD5_128_AUTHENTICATION_CODE_LENGTH; + else /* IPMI_INTEGRITY_ALGORITHM_HMAC_SHA256_128 */ + authentication_code_len = IPMI_HMAC_SHA256_128_AUTHENTICATION_CODE_LENGTH; return (authentication_code_len); } @@ -1063,7 +1066,8 @@ assert ((integrity_algorithm == IPMI_INTEGRITY_ALGORITHM_HMAC_SHA1_96 || integrity_algorithm == IPMI_INTEGRITY_ALGORITHM_HMAC_MD5_128 - || integrity_algorithm == IPMI_INTEGRITY_ALGORITHM_MD5_128) + || integrity_algorithm == IPMI_INTEGRITY_ALGORITHM_MD5_128 + || integrity_algorithm == IPMI_INTEGRITY_ALGORITHM_HMAC_SHA256_128) && !(integrity_algorithm == IPMI_INTEGRITY_ALGORITHM_MD5_128 && authentication_code_data && authentication_code_data_len > IPMI_2_0_MAX_PASSWORD_LENGTH) @@ -1125,13 +1129,20 @@ expected_digest_len = IPMI_HMAC_MD5_DIGEST_LENGTH; copy_digest_len = IPMI_HMAC_MD5_128_AUTHENTICATION_CODE_LENGTH; } - else + else if (integrity_algorithm == IPMI_INTEGRITY_ALGORITHM_MD5_128) { hash_algorithm = IPMI_CRYPT_HASH_MD5; hash_flags = 0; expected_digest_len = MD5_DIGEST_LENGTH; copy_digest_len = IPMI_MD5_128_AUTHENTICATION_CODE_LENGTH; } + else /* IPMI_INTEGRITY_ALGORITHM_HMAC_SHA256_128 */ + { + hash_algorithm = IPMI_CRYPT_HASH_SHA256; + hash_flags = IPMI_CRYPT_HASH_FLAGS_HMAC; + expected_digest_len = IPMI_HMAC_SHA256_DIGEST_LENGTH; + copy_digest_len = IPMI_HMAC_SHA256_128_AUTHENTICATION_CODE_LENGTH; + } if ((crypt_digest_len = ipmi_crypt_hash_digest_len (hash_algorithm)) < 0) { @@ -1353,7 +1364,8 @@ && payload_authenticated == IPMI_PAYLOAD_FLAG_AUTHENTICATED && !(integrity_algorithm == IPMI_INTEGRITY_ALGORITHM_HMAC_SHA1_96 || integrity_algorithm == IPMI_INTEGRITY_ALGORITHM_HMAC_MD5_128 - || integrity_algorithm == IPMI_INTEGRITY_ALGORITHM_MD5_128)) + || integrity_algorithm == IPMI_INTEGRITY_ALGORITHM_MD5_128 + || integrity_algorithm == IPMI_INTEGRITY_ALGORITHM_HMAC_SHA256_128)) || (confidentiality_algorithm == IPMI_CONFIDENTIALITY_ALGORITHM_NONE && payload_encrypted != IPMI_PAYLOAD_FLAG_UNENCRYPTED)) { @@ -2378,7 +2390,8 @@ && payload_authenticated == IPMI_PAYLOAD_FLAG_AUTHENTICATED && !(integrity_algorithm == IPMI_INTEGRITY_ALGORITHM_HMAC_SHA1_96 || integrity_algorithm == IPMI_INTEGRITY_ALGORITHM_HMAC_MD5_128 - || integrity_algorithm == IPMI_INTEGRITY_ALGORITHM_MD5_128)) + || integrity_algorithm == IPMI_INTEGRITY_ALGORITHM_MD5_128 + || integrity_algorithm == IPMI_INTEGRITY_ALGORITHM_HMAC_SHA256_128)) || (confidentiality_algorithm == IPMI_CONFIDENTIALITY_ALGORITHM_NONE && payload_encrypted != IPMI_PAYLOAD_FLAG_UNENCRYPTED) || !ipmi_payload_len) @@ -2515,8 +2528,10 @@ authentication_code_len = IPMI_HMAC_SHA1_96_AUTHENTICATION_CODE_LENGTH; else if (integrity_algorithm == IPMI_INTEGRITY_ALGORITHM_HMAC_MD5_128) authentication_code_len = IPMI_HMAC_MD5_128_AUTHENTICATION_CODE_LENGTH; - else /* IPMI_INTEGRITY_ALGORITHM_MD5_128 */ + else if (integrity_algorithm == IPMI_INTEGRITY_ALGORITHM_MD5_128) authentication_code_len = IPMI_MD5_128_AUTHENTICATION_CODE_LENGTH; + else /* IPMI_INTEGRITY_ALGORITHM_HMAC_SHA256_128 */ + authentication_code_len = IPMI_HMAC_SHA256_128_AUTHENTICATION_CODE_LENGTH; if ((pad_length_field_len = fiid_template_field_len_bytes (tmpl_rmcpplus_session_trlr, "pad_length")) < 0) { Index: libfreeipmi/src/api/ipmi-lan-session-common.c =================================================================== --- libfreeipmi/src/api/ipmi-lan-session-common.c (revision 7200) +++ libfreeipmi/src/api/ipmi-lan-session-common.c (working copy) @@ -3712,6 +3712,18 @@ goto cleanup; } } + else if (ctx->io.outofband.authentication_algorithm == IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_SHA256 + && keybuf_len == (IPMI_HMAC_SHA256_DIGEST_LENGTH + 1)) + { + if (fiid_obj_set_data (obj_cmd_rs, + "key_exchange_authentication_code", + keybuf, + IPMI_HMAC_SHA256_DIGEST_LENGTH) < 0) + { + API_FIID_OBJECT_ERROR_TO_API_ERRNUM (ctx, obj_cmd_rs); + goto cleanup; + } + } } /* IPMI Workaround (achu) Index: libfreeipmi/src/util/ipmi-cipher-suite-util.c =================================================================== --- libfreeipmi/src/util/ipmi-cipher-suite-util.c (revision 7200) +++ libfreeipmi/src/util/ipmi-cipher-suite-util.c (working copy) @@ -38,9 +38,13 @@ { uint8_t a, i, c; + /* XXX - Errata 4 defines SHA256 but not cipher suite IDs */ + /* Cipher Suite 17 confirmed via DCMI 1.1 specification */ + /* To avoid gcc warnings, add +1 to comparison */ - if (!((cipher_suite_id + 1) >= 1 - && cipher_suite_id <= 14)) + if (!(((cipher_suite_id + 1) >= 1 + && cipher_suite_id <= 14) + || cipher_suite_id == 17)) { SET_ERRNO (EINVAL); return (-1); @@ -50,8 +54,10 @@ a = IPMI_AUTHENTICATION_ALGORITHM_RAKP_NONE; else if (cipher_suite_id >= 1 && cipher_suite_id <= 5) a = IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_SHA1; - else /* cipher_suite_id >= 6 && cipher_suite_id <= 14 */ + else if (cipher_suite_id >= 6 && cipher_suite_id <= 14) a = IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_MD5; + else /* cipher_suite_id == 17 */ + a = IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_SHA256; if (cipher_suite_id == 0 || cipher_suite_id == 1 @@ -61,8 +67,10 @@ i = IPMI_INTEGRITY_ALGORITHM_HMAC_SHA1_96; else if (cipher_suite_id >= 7 && cipher_suite_id <= 10) i = IPMI_INTEGRITY_ALGORITHM_HMAC_MD5_128; - else /* cipher_suite_id >= 11 && cipher_suite_id <= 14 */ + else if (cipher_suite_id >= 11 && cipher_suite_id <= 14) i = IPMI_INTEGRITY_ALGORITHM_MD5_128; + else /* cipher_suite_id == 17 */ + i = IPMI_INTEGRITY_ALGORITHM_HMAC_SHA256_128; if (cipher_suite_id == 0 || cipher_suite_id == 1 @@ -73,15 +81,16 @@ c = IPMI_CONFIDENTIALITY_ALGORITHM_NONE; else if (cipher_suite_id == 3 || cipher_suite_id == 8 - || cipher_suite_id == 12) + || cipher_suite_id == 12 + || cipher_suite_id == 17) c = IPMI_CONFIDENTIALITY_ALGORITHM_AES_CBC_128; else if (cipher_suite_id == 4 || cipher_suite_id == 9 || cipher_suite_id == 13) c = IPMI_CONFIDENTIALITY_ALGORITHM_XRC4_128; else /* cipher_suite_id == 5 - || cipher_suite_id == 10 - || cipher_suite_id == 14 */ + || cipher_suite_id == 10 + || cipher_suite_id == 14 */ c = IPMI_CONFIDENTIALITY_ALGORITHM_XRC4_40; if (authentication_algorithm) @@ -133,7 +142,7 @@ *cipher_suite_id = 5; } } - else /* authentication_algorithm == IPMI_INTEGRITY_ALGORITHM_HMAC_MD5_128 */ + else if (authentication_algorithm == IPMI_INTEGRITY_ALGORITHM_HMAC_MD5_128) { if (integrity_algorithm == IPMI_INTEGRITY_ALGORITHM_NONE && confidentiality_algorithm == IPMI_CONFIDENTIALITY_ALGORITHM_NONE) @@ -161,6 +170,10 @@ *cipher_suite_id = 14; } } + else if (authentication_algorithm == IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_SHA256 + && integrity_algorithm == IPMI_INTEGRITY_ALGORITHM_HMAC_SHA256_128 + && confidentiality_algorithm == IPMI_CONFIDENTIALITY_ALGORITHM_AES_CBC_128) + *cipher_suite_id = 17; return (0); } Index: libfreeipmi/src/util/ipmi-rmcpplus-util.c =================================================================== --- libfreeipmi/src/util/ipmi-rmcpplus-util.c (revision 7200) +++ libfreeipmi/src/util/ipmi-rmcpplus-util.c (working copy) @@ -79,7 +79,8 @@ /* k_g can be NULL, indicating a empty k_g */ if ((authentication_algorithm != IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_SHA1 - && authentication_algorithm != IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_MD5) + && authentication_algorithm != IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_MD5 + && authentication_algorithm != IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_SHA256) || (k_g && !k_g_len) || (k_g && k_g_len > IPMI_MAX_K_G_LENGTH) || !remote_console_random_number @@ -104,12 +105,18 @@ hash_flags = IPMI_CRYPT_HASH_FLAGS_HMAC; expected_digest_len = IPMI_HMAC_SHA1_DIGEST_LENGTH; } - else /* IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_MD5 */ + else if (authentication_algorithm == IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_MD5) { hash_algorithm = IPMI_CRYPT_HASH_MD5; hash_flags = IPMI_CRYPT_HASH_FLAGS_HMAC; expected_digest_len = IPMI_HMAC_MD5_DIGEST_LENGTH; } + else /* IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_SHA256 */ + { + hash_algorithm = IPMI_CRYPT_HASH_SHA256; + hash_flags = IPMI_CRYPT_HASH_FLAGS_HMAC; + expected_digest_len = IPMI_HMAC_SHA256_DIGEST_LENGTH; + } if ((crypt_digest_len = ipmi_crypt_hash_digest_len (hash_algorithm)) < 0) { @@ -315,6 +322,36 @@ } static int +_calculate_k_rakp_hmac_sha256 (const void *sik_key, + unsigned int sik_key_len, + void *k, + unsigned int k_len, + const void *constant, + unsigned int constant_len) +{ + if (!sik_key + || !sik_key_len + || !k + || !k_len + || !constant + || !constant_len + || (constant_len < IPMI_KEY_CONSTANT_LENGTH)) + { + SET_ERRNO (EINVAL); + return (-1); + } + + return (_calculate_k_rakp_hmac (IPMI_CRYPT_HASH_SHA256, + IPMI_HMAC_SHA256_DIGEST_LENGTH, + sik_key, + sik_key_len, + k, + k_len, + constant, + constant_len)); +} + +static int _ipmi_calculate_k (uint8_t authentication_algorithm, const void *sik_key, unsigned int sik_key_len, @@ -324,7 +361,8 @@ unsigned int constant_len) { if ((authentication_algorithm != IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_SHA1 - && authentication_algorithm != IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_MD5) + && authentication_algorithm != IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_MD5 + && authentication_algorithm != IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_SHA256) || !sik_key || !sik_key_len || !k @@ -344,13 +382,20 @@ k_len, constant, constant_len)); - else /* IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_MD5 */ + else if (authentication_algorithm == IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_MD5) return (_calculate_k_rakp_hmac_md5 (sik_key, sik_key_len, k, k_len, constant, constant_len)); + else /* IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_SHA256 */ + return (_calculate_k_rakp_hmac_sha256 (sik_key, + sik_key_len, + k, + k_len, + constant, + constant_len)); } int @@ -472,6 +517,7 @@ else /* authentication_algorithm == IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_SHA1 || authentication_algorithm == IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_MD5 + || authentication_algorithm == IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_SHA256 */ { if ((authentication_code_data_len && !authentication_code_data) @@ -546,7 +592,8 @@ integrity_key_buf_len = 0; } else if (integrity_algorithm == IPMI_INTEGRITY_ALGORITHM_HMAC_SHA1_96 - || integrity_algorithm == IPMI_INTEGRITY_ALGORITHM_HMAC_MD5_128) + || integrity_algorithm == IPMI_INTEGRITY_ALGORITHM_HMAC_MD5_128 + || integrity_algorithm == IPMI_INTEGRITY_ALGORITHM_HMAC_SHA256_128) { if ((k1_len = ipmi_calculate_k1 (authentication_algorithm, sik_key_buf, @@ -658,7 +705,8 @@ if ((authentication_algorithm != IPMI_AUTHENTICATION_ALGORITHM_RAKP_NONE && authentication_algorithm != IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_SHA1 - && authentication_algorithm != IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_MD5) + && authentication_algorithm != IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_MD5 + && authentication_algorithm != IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_SHA256) || (k_uid && !k_uid_len) || (k_uid && k_uid_len > IPMI_2_0_MAX_PASSWORD_LENGTH) || !managed_system_random_number @@ -691,7 +739,7 @@ hash_algorithm = IPMI_CRYPT_HASH_SHA1; hash_flags = IPMI_CRYPT_HASH_FLAGS_HMAC; } - else /* IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_MD5 */ + else if (authentication_algorithm == IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_MD5) { if (key_exchange_authentication_code_len < IPMI_HMAC_MD5_DIGEST_LENGTH) { @@ -703,7 +751,19 @@ hash_algorithm = IPMI_CRYPT_HASH_MD5; hash_flags = IPMI_CRYPT_HASH_FLAGS_HMAC; } + else /* IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_SHA256 */ + { + if (key_exchange_authentication_code_len < IPMI_HMAC_SHA256_DIGEST_LENGTH) + { + SET_ERRNO (EINVAL); + goto cleanup; + } + expected_digest_len = IPMI_HMAC_SHA256_DIGEST_LENGTH; + hash_algorithm = IPMI_CRYPT_HASH_SHA256; + hash_flags = IPMI_CRYPT_HASH_FLAGS_HMAC; + } + /* checks above and memcpy limits below ensure can't overflow unsigned int */ memset (buf, '\0', IPMI_MAX_KEY_DATA_LENGTH); memcpy (buf + buf_index, managed_system_random_number, IPMI_MANAGED_SYSTEM_RANDOM_NUMBER_LENGTH); @@ -911,7 +971,8 @@ if ((authentication_algorithm != IPMI_AUTHENTICATION_ALGORITHM_RAKP_NONE && authentication_algorithm != IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_SHA1 - && authentication_algorithm != IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_MD5) + && authentication_algorithm != IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_MD5 + && authentication_algorithm != IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_SHA256) || (k_uid && !k_uid_len) || (k_uid && k_uid_len > IPMI_2_0_MAX_PASSWORD_LENGTH) || !remote_console_random_number @@ -949,6 +1010,12 @@ hash_algorithm = IPMI_CRYPT_HASH_MD5; hash_flags = IPMI_CRYPT_HASH_FLAGS_HMAC; } + else if (authentication_algorithm == IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_SHA256) + { + compare_len = IPMI_HMAC_SHA256_DIGEST_LENGTH; + hash_algorithm = IPMI_CRYPT_HASH_SHA256; + hash_flags = IPMI_CRYPT_HASH_FLAGS_HMAC; + } if ((key_exchange_authentication_code_len = fiid_obj_get_data (obj_cmd, "key_exchange_authentication_code", @@ -1074,7 +1141,8 @@ if ((authentication_algorithm != IPMI_AUTHENTICATION_ALGORITHM_RAKP_NONE && authentication_algorithm != IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_SHA1 - && authentication_algorithm != IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_MD5) + && authentication_algorithm != IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_MD5 + && authentication_algorithm != IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_SHA256) || !remote_console_random_number || (remote_console_random_number_len < IPMI_REMOTE_CONSOLE_RANDOM_NUMBER_LENGTH) || !managed_system_guid @@ -1116,7 +1184,19 @@ hash_algorithm = IPMI_CRYPT_HASH_MD5; hash_flags = IPMI_CRYPT_HASH_FLAGS_HMAC; } + else if (authentication_algorithm == IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_SHA256) + { + if (!sik_key || sik_key_len < IPMI_HMAC_SHA256_DIGEST_LENGTH) + { + SET_ERRNO (EINVAL); + return (-1); + } + compare_len = IPMI_HMAC_SHA256_128_AUTHENTICATION_CODE_LENGTH; + hash_algorithm = IPMI_CRYPT_HASH_SHA256; + hash_flags = IPMI_CRYPT_HASH_FLAGS_HMAC; + } + if ((integrity_check_value_len = fiid_obj_get_data (obj_cmd, "integrity_check_value", integrity_check_value, @@ -1203,7 +1283,8 @@ if ((integrity_algorithm != IPMI_INTEGRITY_ALGORITHM_NONE && integrity_algorithm != IPMI_INTEGRITY_ALGORITHM_HMAC_SHA1_96 && integrity_algorithm != IPMI_INTEGRITY_ALGORITHM_HMAC_MD5_128 - && integrity_algorithm != IPMI_INTEGRITY_ALGORITHM_MD5_128) + && integrity_algorithm != IPMI_INTEGRITY_ALGORITHM_MD5_128 + && integrity_algorithm != IPMI_INTEGRITY_ALGORITHM_HMAC_SHA256_128) || !pkt || !pkt_len || (authentication_code_data && !authentication_code_data_len) @@ -1234,13 +1315,20 @@ expected_digest_len = IPMI_HMAC_MD5_DIGEST_LENGTH; compare_digest_len = IPMI_HMAC_MD5_128_AUTHENTICATION_CODE_LENGTH; } - else /* IPMI_INTEGRITY_ALGORITHM_MD5_128 */ + else if (integrity_algorithm == IPMI_INTEGRITY_ALGORITHM_MD5_128) { hash_algorithm = IPMI_CRYPT_HASH_MD5; hash_flags = 0; expected_digest_len = IPMI_MD5_DIGEST_LENGTH; compare_digest_len = IPMI_MD5_128_AUTHENTICATION_CODE_LENGTH; } + else /* IPMI_INTEGRITY_ALGORITHM_HMAC_SHA256_128 */ + { + hash_algorithm = IPMI_CRYPT_HASH_SHA256; + hash_flags = IPMI_CRYPT_HASH_FLAGS_HMAC; + expected_digest_len = IPMI_HMAC_SHA256_DIGEST_LENGTH; + compare_digest_len = IPMI_HMAC_SHA256_128_AUTHENTICATION_CODE_LENGTH; + } if ((crypt_digest_len = ipmi_crypt_hash_digest_len (hash_algorithm)) < 0) { Index: common/man/manpage-common-cipher-suite-id-details.man =================================================================== --- common/man/manpage-common-cipher-suite-id-details.man (revision 7200) +++ common/man/manpage-common-cipher-suite-id-details.man (working copy) @@ -28,4 +28,17 @@ .\" 13 - Authentication Algorithm = HMAC-MD5; Integrity Algorithm = MD5-128; Confidentiality Algorithm = xRC4-128 .\" .sp .\" 14 - Authentication Algorithm = HMAC-MD5; Integrity Algorithm = MD5-128; Confidentiality Algorithm = xRC4-40 - +.\" XXX GUESS +.\" .sp +.\" 15 - Authentication Algorithm = HMAC-SHA256; Integrity Algorithm = None; Confidentiality Algorithm = None +.\" XXX GUESS +.\" .sp +.\" 16 - Authentication Algorithm = HMAC-SHA256; Integrity Algorithm = HMAC_SHA256_128; Confidentiality Algorithm = None +.sp +17 - Authentication Algorithm = HMAC-SHA256; Integrity Algorithm = HMAC_SHA256_128; Confidentiality Algorithm = AES-CBC-128 +.\" XXX GUESS +.\" .sp +.\" 18 - Authentication Algorithm = HMAC-SHA256; Integrity Algorithm = HMAC_SHA256_128; Confidentiality Algorithm = xRC4-128 +.\" XXX GUESS +.\" .sp +.\" 19 - Authentication Algorithm = HMAC-SHA256; Integrity Algorithm = HMAC_SHA256_128; Confidentiality Algorithm = xRC4-40