1 /* 2 * Copyright (C) 2003-2015 FreeIPMI Core Team 3 * 4 * This program is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation, either version 3 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program. If not, see <http://www.gnu.org/licenses/>. 16 * 17 */ 18 19 #ifndef IPMI_RMCPPLUS_INTERFACE_H 20 #define IPMI_RMCPPLUS_INTERFACE_H 21 22 #ifdef __cplusplus 23 extern "C" { 24 #endif 25 26 #include <stdint.h> 27 #include <freeipmi/fiid/fiid.h> 28 29 #include <sys/types.h> 30 #include <sys/socket.h> 31 32 /************************** 33 * IPMI 2.0 Payload Types * 34 **************************/ 35 36 #define IPMI_PAYLOAD_TYPE_IPMI 0x00 37 #define IPMI_PAYLOAD_TYPE_SOL 0x01 38 #define IPMI_PAYLOAD_TYPE_OEM_EXPLICIT 0x02 39 #define IPMI_PAYLOAD_TYPE_RMCPPLUS_OPEN_SESSION_REQUEST 0x10 40 #define IPMI_PAYLOAD_TYPE_RMCPPLUS_OPEN_SESSION_RESPONSE 0x11 41 #define IPMI_PAYLOAD_TYPE_RAKP_MESSAGE_1 0x12 42 #define IPMI_PAYLOAD_TYPE_RAKP_MESSAGE_2 0x13 43 #define IPMI_PAYLOAD_TYPE_RAKP_MESSAGE_3 0x14 44 #define IPMI_PAYLOAD_TYPE_RAKP_MESSAGE_4 0x15 45 /* 20h - 27h - OEM */ 46 /* all other reserved */ 47 48 #define IPMI_PAYLOAD_TYPE_VALID(__payload_type) \ 49 (((__payload_type) == IPMI_PAYLOAD_TYPE_IPMI \ 50 || (__payload_type) == IPMI_PAYLOAD_TYPE_SOL \ 51 || (__payload_type) == IPMI_PAYLOAD_TYPE_OEM_EXPLICIT \ 52 || (__payload_type) == IPMI_PAYLOAD_TYPE_RMCPPLUS_OPEN_SESSION_REQUEST \ 53 || (__payload_type) == IPMI_PAYLOAD_TYPE_RMCPPLUS_OPEN_SESSION_RESPONSE \ 54 || (__payload_type) == IPMI_PAYLOAD_TYPE_RAKP_MESSAGE_1 \ 55 || (__payload_type) == IPMI_PAYLOAD_TYPE_RAKP_MESSAGE_2 \ 56 || (__payload_type) == IPMI_PAYLOAD_TYPE_RAKP_MESSAGE_3 \ 57 || (__payload_type) == IPMI_PAYLOAD_TYPE_RAKP_MESSAGE_4) ? 1 : 0) 58 59 #define IPMI_PAYLOAD_TYPE_SESSION_SETUP(__payload_type) \ 60 (((__payload_type) == IPMI_PAYLOAD_TYPE_RMCPPLUS_OPEN_SESSION_REQUEST \ 61 || (__payload_type) == IPMI_PAYLOAD_TYPE_RMCPPLUS_OPEN_SESSION_RESPONSE \ 62 || (__payload_type) == IPMI_PAYLOAD_TYPE_RAKP_MESSAGE_1 \ 63 || (__payload_type) == IPMI_PAYLOAD_TYPE_RAKP_MESSAGE_2 \ 64 || (__payload_type) == IPMI_PAYLOAD_TYPE_RAKP_MESSAGE_3 \ 65 || (__payload_type) == IPMI_PAYLOAD_TYPE_RAKP_MESSAGE_4) ? 1 : 0) 66 67 /************************** 68 * IPMI 2.0 Payload Flags * 69 **************************/ 70 #define IPMI_PAYLOAD_FLAG_UNENCRYPTED 0x0 71 #define IPMI_PAYLOAD_FLAG_ENCRYPTED 0x1 72 #define IPMI_PAYLOAD_FLAG_UNAUTHENTICATED 0x0 73 #define IPMI_PAYLOAD_FLAG_AUTHENTICATED 0x1 74 75 #define IPMI_PAYLOAD_ENCRYPTED_FLAG_VALID(__payload_flag) \ 76 (((__payload_flag) == IPMI_PAYLOAD_FLAG_UNENCRYPTED \ 77 || (__payload_flag) == IPMI_PAYLOAD_FLAG_ENCRYPTED) ? 1 : 0) 78 79 #define IPMI_PAYLOAD_AUTHENTICATED_FLAG_VALID(__payload_flag) \ 80 (((__payload_flag) == IPMI_PAYLOAD_FLAG_UNENCRYPTED \ 81 || (__payload_flag) == IPMI_PAYLOAD_FLAG_ENCRYPTED) ? 1 : 0) 82 83 /********************************************* 84 * IPMI 2.0 Authentication Algorithm Numbers * 85 *********************************************/ 86 87 #define IPMI_AUTHENTICATION_ALGORITHM_RAKP_NONE 0x00 88 #define IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_SHA1 0x01 89 #define IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_MD5 0x02 90 #define IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_SHA256 0x03 91 /* C0h - FFh - OEM */ 92 /* all other reserved */ 93 94 #define IPMI_AUTHENTICATION_ALGORITHM_VALID(__algorithm) \ 95 (((__algorithm) == IPMI_AUTHENTICATION_ALGORITHM_RAKP_NONE \ 96 || (__algorithm) == IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_SHA1 \ 97 || (__algorithm) == IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_MD5 \ 98 || (__algorithm) == IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_SHA256) ? 1 : 0) 99 100 #define IPMI_AUTHENTICATION_ALGORITHM_SUPPORTED(__algorithm) \ 101 (((__algorithm) == IPMI_AUTHENTICATION_ALGORITHM_RAKP_NONE \ 102 || (__algorithm) == IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_SHA1 \ 103 || (__algorithm) == IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_MD5 \ 104 || (__algorithm) == IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_SHA256) ? 1 : 0) 105 106 /**************************************** 107 * IPMI 2.0 Integrity Algorithm Numbers * 108 ****************************************/ 109 110 #define IPMI_INTEGRITY_ALGORITHM_NONE 0x00 111 #define IPMI_INTEGRITY_ALGORITHM_HMAC_SHA1_96 0x01 112 #define IPMI_INTEGRITY_ALGORITHM_HMAC_MD5_128 0x02 113 #define IPMI_INTEGRITY_ALGORITHM_MD5_128 0x03 114 #define IPMI_INTEGRITY_ALGORITHM_HMAC_SHA256_128 0x04 115 /* C0h - FFh - OEM */ 116 /* all other reserved */ 117 118 #define IPMI_INTEGRITY_ALGORITHM_VALID(__algorithm) \ 119 (((__algorithm) == IPMI_INTEGRITY_ALGORITHM_NONE \ 120 || (__algorithm) == IPMI_INTEGRITY_ALGORITHM_HMAC_SHA1_96 \ 121 || (__algorithm) == IPMI_INTEGRITY_ALGORITHM_HMAC_MD5_128 \ 122 || (__algorithm) == IPMI_INTEGRITY_ALGORITHM_MD5_128 \ 123 || (__algorithm) == IPMI_INTEGRITY_ALGORITHM_HMAC_SHA256_128) ? 1 : 0) 124 125 #define IPMI_INTEGRITY_ALGORITHM_SUPPORTED(__algorithm) \ 126 (((__algorithm) == IPMI_INTEGRITY_ALGORITHM_NONE \ 127 || (__algorithm) == IPMI_INTEGRITY_ALGORITHM_HMAC_SHA1_96 \ 128 || (__algorithm) == IPMI_INTEGRITY_ALGORITHM_HMAC_MD5_128 \ 129 || (__algorithm) == IPMI_INTEGRITY_ALGORITHM_MD5_128 \ 130 || (__algorithm) == IPMI_INTEGRITY_ALGORITHM_HMAC_SHA256_128) ? 1 : 0) 131 132 /********************************************** 133 * IPMI 2.0 Confidentiality Algorithm Numbers * 134 **********************************************/ 135 136 #define IPMI_CONFIDENTIALITY_ALGORITHM_NONE 0x00 137 #define IPMI_CONFIDENTIALITY_ALGORITHM_AES_CBC_128 0x01 138 #define IPMI_CONFIDENTIALITY_ALGORITHM_XRC4_128 0x02 139 #define IPMI_CONFIDENTIALITY_ALGORITHM_XRC4_40 0x03 140 /* 30h - 3Fh - OEM */ 141 /* all other reserved */ 142 143 #define IPMI_CONFIDENTIALITY_ALGORITHM_VALID(__algorithm) \ 144 (((__algorithm) == IPMI_CONFIDENTIALITY_ALGORITHM_NONE \ 145 || (__algorithm) == IPMI_CONFIDENTIALITY_ALGORITHM_AES_CBC_128 \ 146 || (__algorithm) == IPMI_CONFIDENTIALITY_ALGORITHM_XRC4_128 \ 147 || (__algorithm) == IPMI_CONFIDENTIALITY_ALGORITHM_XRC4_40) ? 1 : 0) 148 149 #define IPMI_CONFIDENTIALITY_ALGORITHM_SUPPORTED(__algorithm) \ 150 (((__algorithm) == IPMI_CONFIDENTIALITY_ALGORITHM_NONE \ 151 || (__algorithm) == IPMI_CONFIDENTIALITY_ALGORITHM_AES_CBC_128) ? 1 : 0) 152 153 /*************************************** 154 * IPMI 2.0 Misc Flags and Definitions * 155 ***************************************/ 156 157 #define IPMI_AUTHENTICATION_PAYLOAD_TYPE 0x00 158 #define IPMI_AUTHENTICATION_PAYLOAD_LENGTH 0x08 159 #define IPMI_INTEGRITY_PAYLOAD_TYPE 0x01 160 #define IPMI_INTEGRITY_PAYLOAD_LENGTH 0x08 161 #define IPMI_CONFIDENTIALITY_PAYLOAD_TYPE 0x02 162 #define IPMI_CONFIDENTIALITY_PAYLOAD_LENGTH 0x08 163 164 #define IPMI_USER_NAME_PRIVILEGE_LOOKUP 0x0 165 #define IPMI_NAME_ONLY_LOOKUP 0x1 166 167 #define IPMI_USER_NAME_LOOKUP_VALID(__username_lookup_flag) \ 168 (((__username_lookup_flag) == IPMI_USER_NAME_PRIVILEGE_LOOKUP \ 169 || (__username_lookup_flag) == IPMI_NAME_ONLY_LOOKUP) ? 1 : 0) 170 171 #define IPMI_REMOTE_CONSOLE_RANDOM_NUMBER_LENGTH 16 172 #define IPMI_MANAGED_SYSTEM_RANDOM_NUMBER_LENGTH 16 173 #define IPMI_MANAGED_SYSTEM_GUID_LENGTH 16 174 175 #define IPMI_NEXT_HEADER 0x07 176 177 #define IPMI_INTEGRITY_PAD_MULTIPLE 4 178 #define IPMI_INTEGRITY_PAD_DATA 0xFF 179 180 #define IPMI_MAX_PAYLOAD_LENGTH 65536 181 /* achu: b/c ipmi_msg_len is 2 bytes */ 182 183 #define IPMI_HMAC_SHA1_DIGEST_LENGTH 20 184 #define IPMI_HMAC_MD5_DIGEST_LENGTH 16 185 #define IPMI_MD5_DIGEST_LENGTH 16 186 #define IPMI_HMAC_SHA1_96_DIGEST_LENGTH 12 187 #define IPMI_HMAC_SHA256_DIGEST_LENGTH 32 188 189 #define IPMI_HMAC_SHA1_96_AUTHENTICATION_CODE_LENGTH 12 190 #define IPMI_HMAC_MD5_128_AUTHENTICATION_CODE_LENGTH 16 191 #define IPMI_MD5_128_AUTHENTICATION_CODE_LENGTH 16 192 #define IPMI_HMAC_SHA256_128_AUTHENTICATION_CODE_LENGTH 16 193 194 /* Refer to table 22-19 */ 195 /* XXX - Errata 4 defines SHA256 but not cipher suite IDs */ 196 /* achu: Intel support says Cipher Suite 15-19 maps to 1-5 using 197 * SHA256 instead of SHA1 and SHA256-128 instead of SHA1-96. 198 */ 199 /* Cipher Suite 17 confirmed via DCMI 1.1 specification */ 200 #define IPMI_CIPHER_SUITE_ID_MIN 0 201 #define IPMI_CIPHER_SUITE_ID_MAX 19 202 203 /* 204 * fill* functions return 0 on success, -1 on error. 205 * 206 * object must be for the fill function's respective fiid 207 * template. 208 * 209 * assemble/unassemble functions must be passed fiid objects of the 210 * respective expected header/trailer templates. 211 * 212 * see freeipmi/templates/ for template definitions 213 */ 214 215 extern fiid_template_t tmpl_rmcpplus_session_hdr; 216 extern fiid_template_t tmpl_rmcpplus_session_trlr; 217 218 extern fiid_template_t tmpl_rmcpplus_payload; 219 220 extern fiid_template_t tmpl_rmcpplus_open_session_request; 221 extern fiid_template_t tmpl_rmcpplus_open_session_response; 222 extern fiid_template_t tmpl_rmcpplus_rakp_message_1; 223 extern fiid_template_t tmpl_rmcpplus_rakp_message_2; 224 extern fiid_template_t tmpl_rmcpplus_rakp_message_3; 225 extern fiid_template_t tmpl_rmcpplus_rakp_message_4; 226 227 /* ipmi_rmcpplus_init 228 * 229 * Must be called first to initialize crypt libs. In threaded 230 * programs, must be called before threads are created. 231 * 232 * If errno returned == EPERM, underlying crypt library incompatible. 233 * 234 * Returns 0 on success, -1 on error. 235 */ 236 int ipmi_rmcpplus_init (void); 237 238 int fill_rmcpplus_session_hdr (uint8_t payload_type, 239 uint8_t payload_authenticated, 240 uint8_t payload_encrypted, 241 uint32_t oem_iana, 242 uint16_t oem_payload_id, 243 uint32_t session_id, 244 uint32_t session_sequence_number, 245 fiid_obj_t obj_rmcpplus_session_hdr); 246 247 int fill_rmcpplus_session_trlr (fiid_obj_t obj_rmcpplus_session_trlr); 248 249 int fill_rmcpplus_payload (const void *confidentiality_header, 250 unsigned int confidentiality_header_len, 251 const void *payload_data, 252 unsigned int payload_data_len, 253 const void *confidentiality_trailer, 254 unsigned int confidentiality_trailer_len, 255 fiid_obj_t obj_cmd_rq); 256 257 int fill_rmcpplus_open_session (uint8_t message_tag, 258 uint8_t requested_maximum_privilege_level, 259 uint32_t remote_console_session_id, 260 uint8_t authentication_algorithm, 261 uint8_t integrity_algorithm, 262 uint8_t confidentiality_algorithm, 263 fiid_obj_t obj_cmd_rq); 264 265 int fill_rmcpplus_rakp_message_1 (uint8_t message_tag, 266 uint32_t managed_system_session_id, 267 const void *remote_console_random_number, 268 unsigned int remote_console_random_number_len, 269 uint8_t requested_maximum_privilege_level, 270 uint8_t name_only_lookup_flag, 271 const char *username, 272 unsigned int username_len, 273 fiid_obj_t obj_cmd_rq); 274 275 int fill_rmcpplus_rakp_message_3 (uint8_t message_tag, 276 uint8_t rmcpplus_status_code, 277 uint32_t managed_system_session_id, 278 const void *key_exchange_authentication_code, 279 unsigned int key_exchange_authentication_code_len, 280 fiid_obj_t obj_cmd_rq); 281 282 /* returns length written to pkt on success, -1 on error */ 283 int assemble_ipmi_rmcpplus_pkt (uint8_t authentication_algorithm, 284 uint8_t integrity_algorithm, 285 uint8_t confidentiality_algorithm, 286 const void *integrity_key, 287 unsigned int integrity_key_len, 288 const void *confidentiality_key, 289 unsigned int confidentiality_key_len, 290 const void *authentication_code_data, 291 unsigned int authentication_code_data_len, 292 fiid_obj_t obj_rmcp_hdr, 293 fiid_obj_t obj_rmcpplus_session_hdr, 294 fiid_obj_t obj_lan_msg_hdr, 295 fiid_obj_t obj_cmd, 296 fiid_obj_t obj_rmcpplus_session_trlr, 297 void *pkt, 298 unsigned int pkt_len, 299 unsigned int flags); 300 301 /* returns 1 if fully unparsed, 0 if not, -1 on error */ 302 int unassemble_ipmi_rmcpplus_pkt (uint8_t authentication_algorithm, 303 uint8_t integrity_algorithm, 304 uint8_t confidentiality_algorithm, 305 const void *integrity_key, 306 unsigned int integrity_key_len, 307 const void *confidentiality_key, 308 unsigned int confidentiality_key_len, 309 const void *pkt, 310 unsigned int pkt_len, 311 fiid_obj_t obj_rmcp_hdr, 312 fiid_obj_t obj_rmcpplus_session_hdr, 313 fiid_obj_t obj_rmcpplus_payload, 314 fiid_obj_t obj_lan_msg_hdr, 315 fiid_obj_t obj_cmd, 316 fiid_obj_t obj_lan_msg_trlr, 317 fiid_obj_t obj_rmcpplus_session_trlr, 318 unsigned int flags); 319 320 /* returns length sent on success, -1 on error */ 321 /* A few extra error checks, but nearly identical to system sendto() */ 322 ssize_t ipmi_rmcpplus_sendto (int s, 323 const void *buf, 324 size_t len, 325 int flags, 326 const struct sockaddr *to, 327 socklen_t tolen); 328 329 /* returns length received on success, 0 on orderly shutdown, -1 on error */ 330 /* A few extra error checks, but nearly identical to system recvfrom() */ 331 ssize_t ipmi_rmcpplus_recvfrom (int s, 332 void *buf, 333 size_t len, 334 int flags, 335 struct sockaddr *from, 336 socklen_t *fromlen); 337 338 #ifdef __cplusplus 339 } 340 #endif 341 342 #endif /* IPMI_RMCPPLUS_INTERFACE_H */ 343