Hey Holger,

Finally got your patch merged in.  Added the manpage entries and the
debug support.  Do you think you could try out the final patch below to
make sure I didn't break anything?  Could you also try --debug in a tool
to see if the debug output comes out looking right too?

Thanks,

Al

On Thu, 2010-07-29 at 06:07 -0700, Liebig, Holger wrote:
> Hi all,
> please find attached the required modification for SHA256 and Cipher Suite 17 
> support in freeipmi. SHA256 has been added in IPMI 2.0 Errata 4 and is also 
> one of the recommended Cipher Suites of the upcoming DCMI 1.1 Specification 
> (where the Cipher Suite number is taken from). The modifications itself are 
> straight forward, I just had to find all the places.
> 
> Comments or feedback is more than welcome, especially if it works with other 
> vendor implementations.
> 
> Thanks,
> Holger
> 
> 
> 
> 
> 
-- 
Albert Chu
[email protected]
Computer Scientist
High Performance Systems Division
Lawrence Livermore National Laboratory
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 <freeipmi/interface/ipmi-rmcpplus-interface.h>
 
 #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
_______________________________________________
Freeipmi-devel mailing list
[email protected]
http://lists.gnu.org/mailman/listinfo/freeipmi-devel

Reply via email to