14e57adabSTom Joseph #pragma once 24e57adabSTom Joseph 34e57adabSTom Joseph #include "message.hpp" 44e57adabSTom Joseph #include "session.hpp" 54e57adabSTom Joseph 64e57adabSTom Joseph namespace message 74e57adabSTom Joseph { 84e57adabSTom Joseph 94e57adabSTom Joseph namespace parser 104e57adabSTom Joseph { 114e57adabSTom Joseph 124e57adabSTom Joseph constexpr size_t RMCP_VERSION = 6; 134e57adabSTom Joseph 144e57adabSTom Joseph // RMCP Messages with class=IPMI should be sent with an RMCP Sequence 154e57adabSTom Joseph // Number of FFh to indicate that an RMCP ACK message should not be 164e57adabSTom Joseph // generated by the message receiver. 174e57adabSTom Joseph constexpr size_t RMCP_SEQ = 0xFF; 184e57adabSTom Joseph 194e57adabSTom Joseph // RMCP Message Class 7h is for IPMI 204e57adabSTom Joseph constexpr size_t RMCP_MESSAGE_CLASS_IPMI = 7; 214e57adabSTom Joseph 2264703f4dSTom Joseph // RMCP Session Header Size 2364703f4dSTom Joseph constexpr size_t RMCP_SESSION_HEADER_SIZE = 4; 2464703f4dSTom Joseph 251efcb493STom Joseph // Maximum payload size 261efcb493STom Joseph constexpr size_t MAX_PAYLOAD_SIZE = 255; 271efcb493STom Joseph 284e57adabSTom Joseph enum class SessionHeader 294e57adabSTom Joseph { 304e57adabSTom Joseph IPMI15 = 0x00, 314e57adabSTom Joseph IPMI20 = 0x06, 324e57adabSTom Joseph INVALID = 0xFF, 334e57adabSTom Joseph }; 344e57adabSTom Joseph 354e57adabSTom Joseph struct BasicHeader_t 364e57adabSTom Joseph { 374e57adabSTom Joseph // RMCP Header 384e57adabSTom Joseph uint8_t version; 394e57adabSTom Joseph uint8_t reserved; 404e57adabSTom Joseph uint8_t rmcpSeqNum; 414e57adabSTom Joseph uint8_t classOfMsg; 424e57adabSTom Joseph 434e57adabSTom Joseph // IPMI partial session header 444e57adabSTom Joseph union 454e57adabSTom Joseph { 464e57adabSTom Joseph uint8_t reserved1 : 4; 474e57adabSTom Joseph uint8_t authType : 4; 484e57adabSTom Joseph uint8_t formatType; 494e57adabSTom Joseph } format; 504e57adabSTom Joseph } __attribute__((packed)); 514e57adabSTom Joseph 523563f8feSTom Joseph /** 534e57adabSTom Joseph * @brief Unflatten an incoming packet and prepare the IPMI message 544e57adabSTom Joseph * 554e57adabSTom Joseph * @param[in] inPacket - Incoming IPMI packet 564e57adabSTom Joseph * 574e57adabSTom Joseph * @return A tuple with IPMI message and the session header type to sent the 584e57adabSTom Joseph * response packet. In case of success incoming message and session 594e57adabSTom Joseph * header type. In case of failure nullptr and session header type 604e57adabSTom Joseph * would be invalid. 614e57adabSTom Joseph */ 62*d999ffc1SVernon Mauery std::tuple<std::shared_ptr<Message>, SessionHeader> 639e801a2bSVernon Mauery unflatten(std::vector<uint8_t>& inPacket); 644e57adabSTom Joseph 653563f8feSTom Joseph /** 664e57adabSTom Joseph * @brief Flatten an IPMI message and generate the IPMI packet with the 674e57adabSTom Joseph * session header 684e57adabSTom Joseph * 694e57adabSTom Joseph * @param[in] outMessage - IPMI message to be flattened 704e57adabSTom Joseph * @param[in] authType - Session header type to be added to the IPMI 714e57adabSTom Joseph * packet 724e57adabSTom Joseph * 734e57adabSTom Joseph * @return IPMI packet on success 744e57adabSTom Joseph */ 75*d999ffc1SVernon Mauery std::vector<uint8_t> flatten(std::shared_ptr<Message> outMessage, 76*d999ffc1SVernon Mauery SessionHeader authType, session::Session& session); 774e57adabSTom Joseph 784e57adabSTom Joseph } // namespace parser 794e57adabSTom Joseph 804e57adabSTom Joseph namespace ipmi15parser 814e57adabSTom Joseph { 824e57adabSTom Joseph 834e57adabSTom Joseph struct SessionHeader_t 844e57adabSTom Joseph { 854e57adabSTom Joseph struct parser::BasicHeader_t base; 864e57adabSTom Joseph uint32_t sessSeqNum; 874e57adabSTom Joseph uint32_t sessId; 884e57adabSTom Joseph // <Optional Field: AuthCode> 894e57adabSTom Joseph uint8_t payloadLength; 904e57adabSTom Joseph } __attribute__((packed)); 914e57adabSTom Joseph 924e57adabSTom Joseph struct SessionTrailer_t 934e57adabSTom Joseph { 944e57adabSTom Joseph uint8_t legacyPad; 954e57adabSTom Joseph } __attribute__((packed)); 964e57adabSTom Joseph 973563f8feSTom Joseph /** 984e57adabSTom Joseph * @brief Unflatten an incoming packet and prepare the IPMI message 994e57adabSTom Joseph * 1004e57adabSTom Joseph * @param[in] inPacket - Incoming IPMI packet 1014e57adabSTom Joseph * 1024e57adabSTom Joseph * @return IPMI message in the packet on success 1034e57adabSTom Joseph */ 104*d999ffc1SVernon Mauery std::shared_ptr<Message> unflatten(std::vector<uint8_t>& inPacket); 1054e57adabSTom Joseph 1063563f8feSTom Joseph /** 1074e57adabSTom Joseph * @brief Flatten an IPMI message and generate the IPMI packet with the 1084e57adabSTom Joseph * session header 1094e57adabSTom Joseph * 1104e57adabSTom Joseph * @param[in] outMessage - IPMI message to be flattened 1114e57adabSTom Joseph * 1124e57adabSTom Joseph * @return IPMI packet on success 1134e57adabSTom Joseph */ 114*d999ffc1SVernon Mauery std::vector<uint8_t> flatten(std::shared_ptr<Message> outMessage, 115*d999ffc1SVernon Mauery session::Session& session); 1164e57adabSTom Joseph 1174e57adabSTom Joseph } // namespace ipmi15parser 1184e57adabSTom Joseph 1194e57adabSTom Joseph namespace ipmi20parser 1204e57adabSTom Joseph { 1214e57adabSTom Joseph 1224e57adabSTom Joseph constexpr size_t MAX_INTEGRITY_DATA_LENGTH = 12; 1234e57adabSTom Joseph constexpr size_t PAYLOAD_ENCRYPT_MASK = 0x80; 1244e57adabSTom Joseph constexpr size_t PAYLOAD_AUTH_MASK = 0x40; 1254e57adabSTom Joseph 1264e57adabSTom Joseph struct SessionHeader_t 1274e57adabSTom Joseph { 1284e57adabSTom Joseph struct parser::BasicHeader_t base; 1294e57adabSTom Joseph 1304e57adabSTom Joseph uint8_t payloadType; 1314e57adabSTom Joseph 1324e57adabSTom Joseph uint32_t sessId; 1334e57adabSTom Joseph uint32_t sessSeqNum; 1344e57adabSTom Joseph uint16_t payloadLength; 1354e57adabSTom Joseph } __attribute__((packed)); 1364e57adabSTom Joseph 1374e57adabSTom Joseph struct SessionTrailer_t 1384e57adabSTom Joseph { 1394e57adabSTom Joseph // Integrity Pad 1404e57adabSTom Joseph uint8_t padLength; 1414e57adabSTom Joseph uint8_t nextHeader; 1424e57adabSTom Joseph } __attribute__((packed)); 1434e57adabSTom Joseph 1443563f8feSTom Joseph /** 1454e57adabSTom Joseph * @brief Unflatten an incoming packet and prepare the IPMI message 1464e57adabSTom Joseph * 1474e57adabSTom Joseph * @param[in] inPacket - Incoming IPMI packet 1484e57adabSTom Joseph * 1494e57adabSTom Joseph * @return IPMI message in the packet on success 1504e57adabSTom Joseph */ 151*d999ffc1SVernon Mauery std::shared_ptr<Message> unflatten(std::vector<uint8_t>& inPacket); 1524e57adabSTom Joseph 1533563f8feSTom Joseph /** 1544e57adabSTom Joseph * @brief Flatten an IPMI message and generate the IPMI packet with the 1554e57adabSTom Joseph * session header 1564e57adabSTom Joseph * 1574e57adabSTom Joseph * @param[in] outMessage - IPMI message to be flattened 1584e57adabSTom Joseph * 1594e57adabSTom Joseph * @return IPMI packet on success 1604e57adabSTom Joseph */ 161*d999ffc1SVernon Mauery std::vector<uint8_t> flatten(std::shared_ptr<Message> outMessage, 162*d999ffc1SVernon Mauery session::Session& session); 1634e57adabSTom Joseph 1644e57adabSTom Joseph namespace internal 1654e57adabSTom Joseph { 1664e57adabSTom Joseph 1673563f8feSTom Joseph /** 1684e57adabSTom Joseph * @brief Add sequence number to the message 1694e57adabSTom Joseph * 1704e57adabSTom Joseph * @param[in] packet - outgoing packet to which to add sequence number 1714e57adabSTom Joseph * @param[in] session - session handle 1724e57adabSTom Joseph * 1734e57adabSTom Joseph */ 1744e57adabSTom Joseph void addSequenceNumber(std::vector<uint8_t>& packet, session::Session& session); 1754e57adabSTom Joseph 1763563f8feSTom Joseph /** 17764703f4dSTom Joseph * @brief Verify the integrity data of the incoming IPMI packet 17864703f4dSTom Joseph * 17964703f4dSTom Joseph * @param[in] packet - Incoming IPMI packet 180027dfc2cSTom Joseph * @param[in] message - IPMI Message populated from the incoming packet 181027dfc2cSTom Joseph * @param[in] payloadLen - Length of the IPMI payload 18264703f4dSTom Joseph * 18364703f4dSTom Joseph */ 18464703f4dSTom Joseph bool verifyPacketIntegrity(const std::vector<uint8_t>& packet, 185*d999ffc1SVernon Mauery const std::shared_ptr<Message> message, 186*d999ffc1SVernon Mauery size_t payloadLen); 18764703f4dSTom Joseph 1883563f8feSTom Joseph /** 18964703f4dSTom Joseph * @brief Add Integrity data to the outgoing IPMI packet 19064703f4dSTom Joseph * 19164703f4dSTom Joseph * @param[in] packet - Outgoing IPMI packet 1921404bca6STom Joseph * @param[in] message - IPMI Message populated for the outgoing packet 1931404bca6STom Joseph * @param[in] payloadLen - Length of the IPMI payload 19464703f4dSTom Joseph */ 195*d999ffc1SVernon Mauery void addIntegrityData(std::vector<uint8_t>& packet, 196*d999ffc1SVernon Mauery const std::shared_ptr<Message> message, 1971404bca6STom Joseph size_t payloadLen); 19864703f4dSTom Joseph 1993563f8feSTom Joseph /** 20078478a81STom Joseph * @brief Decrypt the encrypted payload in the incoming IPMI packet 20178478a81STom Joseph * 20278478a81STom Joseph * @param[in] packet - Incoming IPMI packet 20378478a81STom Joseph * @param[in] message - IPMI Message populated from the incoming packet 20478478a81STom Joseph * @param[in] payloadLen - Length of encrypted IPMI payload 20578478a81STom Joseph * 20678478a81STom Joseph * @return on successful completion, return the plain text payload 20778478a81STom Joseph */ 20878478a81STom Joseph std::vector<uint8_t> decryptPayload(const std::vector<uint8_t>& packet, 209*d999ffc1SVernon Mauery const std::shared_ptr<Message> message, 210*d999ffc1SVernon Mauery size_t payloadLen); 21178478a81STom Joseph 2123563f8feSTom Joseph /** 21375362836STom Joseph * @brief Encrypt the plain text payload for the outgoing IPMI packet 21475362836STom Joseph * 21575362836STom Joseph * @param[in] message - IPMI Message populated for the outgoing packet 21675362836STom Joseph * 21775362836STom Joseph * @return on successful completion, return the encrypted payload 21875362836STom Joseph */ 219*d999ffc1SVernon Mauery std::vector<uint8_t> encryptPayload(std::shared_ptr<Message> message); 22075362836STom Joseph 2214e57adabSTom Joseph } // namespace internal 2224e57adabSTom Joseph 2234e57adabSTom Joseph } // namespace ipmi20parser 2244e57adabSTom Joseph 2254e57adabSTom Joseph } // namespace message 226