blob: a992e0afd3df50b12728b499f58f4e7c6eecd1fb [file] [log] [blame]
Tom Joseph4e57ada2016-08-10 06:51:12 -05001#pragma once
2
3#include "message.hpp"
4#include "session.hpp"
5
Andrew Geissler9d9b7632020-05-17 09:18:05 -05006#include <cstddef>
7
Tom Joseph4e57ada2016-08-10 06:51:12 -05008namespace message
9{
10
11namespace parser
12{
13
14constexpr size_t RMCP_VERSION = 6;
15
16// RMCP Messages with class=IPMI should be sent with an RMCP Sequence
17// Number of FFh to indicate that an RMCP ACK message should not be
18// generated by the message receiver.
19constexpr size_t RMCP_SEQ = 0xFF;
20
21// RMCP Message Class 7h is for IPMI
22constexpr size_t RMCP_MESSAGE_CLASS_IPMI = 7;
23
Tom Joseph64703f42017-01-10 17:03:48 +053024// RMCP Session Header Size
25constexpr size_t RMCP_SESSION_HEADER_SIZE = 4;
26
Kirill Pakhomovde7dd5c2021-02-27 18:45:22 +030027// RMCP/ASF Pong Message ASF Header Data Length
28// as per IPMI spec 13.2.4
29constexpr size_t RMCP_ASF_PONG_DATA_LEN = 16;
30
31// ASF IANA
32constexpr uint32_t ASF_IANA = 4542;
33
34// ASF Supported Entities
35constexpr uint32_t ASF_SUPP_ENT = 0x81;
36
37// ASF Supported Entities
38constexpr uint32_t ASF_SUPP_INT = 0x00;
39
Tom Joseph1efcb492017-01-31 16:56:47 +053040// Maximum payload size
41constexpr size_t MAX_PAYLOAD_SIZE = 255;
42
Tom Joseph4e57ada2016-08-10 06:51:12 -050043enum class SessionHeader
44{
45 IPMI15 = 0x00,
46 IPMI20 = 0x06,
47 INVALID = 0xFF,
48};
49
Kirill Pakhomovde7dd5c2021-02-27 18:45:22 +030050// RMCP Header
51struct RmcpHeader_t
Tom Joseph4e57ada2016-08-10 06:51:12 -050052{
53 // RMCP Header
54 uint8_t version;
55 uint8_t reserved;
56 uint8_t rmcpSeqNum;
57 uint8_t classOfMsg;
Kirill Pakhomovde7dd5c2021-02-27 18:45:22 +030058} __attribute__((packed));
59
60struct BasicHeader_t
61{
62 // RMCP Header
63 struct RmcpHeader_t rmcp;
Tom Joseph4e57ada2016-08-10 06:51:12 -050064
65 // IPMI partial session header
66 union
67 {
Vernon Mauery9e801a22018-10-12 13:20:49 -070068 uint8_t reserved1 : 4;
69 uint8_t authType : 4;
Tom Joseph4e57ada2016-08-10 06:51:12 -050070 uint8_t formatType;
71 } format;
72} __attribute__((packed));
73
Tom Joseph3563f8f2017-05-08 15:42:54 +053074/**
Tom Joseph4e57ada2016-08-10 06:51:12 -050075 * @brief Unflatten an incoming packet and prepare the IPMI message
76 *
77 * @param[in] inPacket - Incoming IPMI packet
78 *
79 * @return A tuple with IPMI message and the session header type to sent the
80 * response packet. In case of success incoming message and session
81 * header type. In case of failure nullptr and session header type
82 * would be invalid.
83 */
Vernon Maueryd999ffc2018-10-25 09:16:05 -070084std::tuple<std::shared_ptr<Message>, SessionHeader>
Vernon Mauery9e801a22018-10-12 13:20:49 -070085 unflatten(std::vector<uint8_t>& inPacket);
Tom Joseph4e57ada2016-08-10 06:51:12 -050086
Tom Joseph3563f8f2017-05-08 15:42:54 +053087/**
Tom Joseph4e57ada2016-08-10 06:51:12 -050088 * @brief Flatten an IPMI message and generate the IPMI packet with the
89 * session header
90 *
91 * @param[in] outMessage - IPMI message to be flattened
92 * @param[in] authType - Session header type to be added to the IPMI
93 * packet
94 *
95 * @return IPMI packet on success
96 */
Vernon Maueryd999ffc2018-10-25 09:16:05 -070097std::vector<uint8_t> flatten(std::shared_ptr<Message> outMessage,
Vernon Mauery224f36a2018-10-25 08:52:23 -070098 SessionHeader authType,
99 std::shared_ptr<session::Session> session);
Tom Joseph4e57ada2016-08-10 06:51:12 -0500100
101} // namespace parser
102
103namespace ipmi15parser
104{
105
106struct SessionHeader_t
107{
108 struct parser::BasicHeader_t base;
109 uint32_t sessSeqNum;
110 uint32_t sessId;
111 // <Optional Field: AuthCode>
112 uint8_t payloadLength;
113} __attribute__((packed));
114
115struct SessionTrailer_t
116{
117 uint8_t legacyPad;
118} __attribute__((packed));
119
Tom Joseph3563f8f2017-05-08 15:42:54 +0530120/**
Tom Joseph4e57ada2016-08-10 06:51:12 -0500121 * @brief Unflatten an incoming packet and prepare the IPMI message
122 *
123 * @param[in] inPacket - Incoming IPMI packet
124 *
125 * @return IPMI message in the packet on success
126 */
Vernon Maueryd999ffc2018-10-25 09:16:05 -0700127std::shared_ptr<Message> unflatten(std::vector<uint8_t>& inPacket);
Tom Joseph4e57ada2016-08-10 06:51:12 -0500128
Tom Joseph3563f8f2017-05-08 15:42:54 +0530129/**
Tom Joseph4e57ada2016-08-10 06:51:12 -0500130 * @brief Flatten an IPMI message and generate the IPMI packet with the
131 * session header
132 *
133 * @param[in] outMessage - IPMI message to be flattened
134 *
135 * @return IPMI packet on success
136 */
Vernon Maueryd999ffc2018-10-25 09:16:05 -0700137std::vector<uint8_t> flatten(std::shared_ptr<Message> outMessage,
Vernon Mauery224f36a2018-10-25 08:52:23 -0700138 std::shared_ptr<session::Session> session);
Tom Joseph4e57ada2016-08-10 06:51:12 -0500139
140} // namespace ipmi15parser
141
142namespace ipmi20parser
143{
144
145constexpr size_t MAX_INTEGRITY_DATA_LENGTH = 12;
146constexpr size_t PAYLOAD_ENCRYPT_MASK = 0x80;
147constexpr size_t PAYLOAD_AUTH_MASK = 0x40;
148
149struct SessionHeader_t
150{
151 struct parser::BasicHeader_t base;
152
153 uint8_t payloadType;
154
155 uint32_t sessId;
156 uint32_t sessSeqNum;
157 uint16_t payloadLength;
158} __attribute__((packed));
159
160struct SessionTrailer_t
161{
162 // Integrity Pad
163 uint8_t padLength;
164 uint8_t nextHeader;
Tom Joseph4e57ada2016-08-10 06:51:12 -0500165} __attribute__((packed));
166
Tom Joseph3563f8f2017-05-08 15:42:54 +0530167/**
Tom Joseph4e57ada2016-08-10 06:51:12 -0500168 * @brief Unflatten an incoming packet and prepare the IPMI message
169 *
170 * @param[in] inPacket - Incoming IPMI packet
171 *
172 * @return IPMI message in the packet on success
173 */
Vernon Maueryd999ffc2018-10-25 09:16:05 -0700174std::shared_ptr<Message> unflatten(std::vector<uint8_t>& inPacket);
Tom Joseph4e57ada2016-08-10 06:51:12 -0500175
Tom Joseph3563f8f2017-05-08 15:42:54 +0530176/**
Tom Joseph4e57ada2016-08-10 06:51:12 -0500177 * @brief Flatten an IPMI message and generate the IPMI packet with the
178 * session header
179 *
180 * @param[in] outMessage - IPMI message to be flattened
Lei YUce1f4fc2022-07-12 20:22:17 +0800181 * @param[in] session - session handle
Tom Joseph4e57ada2016-08-10 06:51:12 -0500182 *
183 * @return IPMI packet on success
184 */
Vernon Maueryd999ffc2018-10-25 09:16:05 -0700185std::vector<uint8_t> flatten(std::shared_ptr<Message> outMessage,
Vernon Mauery224f36a2018-10-25 08:52:23 -0700186 std::shared_ptr<session::Session> session);
Tom Joseph4e57ada2016-08-10 06:51:12 -0500187
188namespace internal
189{
190
Tom Joseph3563f8f2017-05-08 15:42:54 +0530191/**
Tom Joseph4e57ada2016-08-10 06:51:12 -0500192 * @brief Add sequence number to the message
193 *
194 * @param[in] packet - outgoing packet to which to add sequence number
195 * @param[in] session - session handle
196 *
197 */
Vernon Mauery224f36a2018-10-25 08:52:23 -0700198void addSequenceNumber(std::vector<uint8_t>& packet,
199 std::shared_ptr<session::Session> session);
Tom Joseph4e57ada2016-08-10 06:51:12 -0500200
Tom Joseph3563f8f2017-05-08 15:42:54 +0530201/**
Tom Joseph64703f42017-01-10 17:03:48 +0530202 * @brief Verify the integrity data of the incoming IPMI packet
203 *
204 * @param[in] packet - Incoming IPMI packet
Tom Joseph027dfc22017-01-26 13:30:53 +0530205 * @param[in] message - IPMI Message populated from the incoming packet
206 * @param[in] payloadLen - Length of the IPMI payload
Lei YUce1f4fc2022-07-12 20:22:17 +0800207 * @param[in] session - session handle
Tom Joseph64703f42017-01-10 17:03:48 +0530208 *
209 */
210bool verifyPacketIntegrity(const std::vector<uint8_t>& packet,
Vernon Maueryd999ffc2018-10-25 09:16:05 -0700211 const std::shared_ptr<Message> message,
Lei YUce1f4fc2022-07-12 20:22:17 +0800212 size_t payloadLen,
213 const std::shared_ptr<session::Session>& session);
Tom Joseph64703f42017-01-10 17:03:48 +0530214
Tom Joseph3563f8f2017-05-08 15:42:54 +0530215/**
Tom Joseph64703f42017-01-10 17:03:48 +0530216 * @brief Add Integrity data to the outgoing IPMI packet
217 *
218 * @param[in] packet - Outgoing IPMI packet
Tom Joseph1404bca2017-01-26 14:17:02 +0530219 * @param[in] message - IPMI Message populated for the outgoing packet
220 * @param[in] payloadLen - Length of the IPMI payload
Tom Joseph64703f42017-01-10 17:03:48 +0530221 */
Vernon Maueryd999ffc2018-10-25 09:16:05 -0700222void addIntegrityData(std::vector<uint8_t>& packet,
Lei YUce1f4fc2022-07-12 20:22:17 +0800223 const std::shared_ptr<Message> message, size_t payloadLen,
224 const std::shared_ptr<session::Session>& session);
Tom Joseph64703f42017-01-10 17:03:48 +0530225
Tom Joseph3563f8f2017-05-08 15:42:54 +0530226/**
Tom Joseph78478a82017-01-26 14:24:29 +0530227 * @brief Decrypt the encrypted payload in the incoming IPMI packet
228 *
229 * @param[in] packet - Incoming IPMI packet
230 * @param[in] message - IPMI Message populated from the incoming packet
231 * @param[in] payloadLen - Length of encrypted IPMI payload
Lei YUce1f4fc2022-07-12 20:22:17 +0800232 * @param[in] session - session handle
Tom Joseph78478a82017-01-26 14:24:29 +0530233 *
234 * @return on successful completion, return the plain text payload
235 */
Lei YUce1f4fc2022-07-12 20:22:17 +0800236std::vector<uint8_t>
237 decryptPayload(const std::vector<uint8_t>& packet,
238 const std::shared_ptr<Message> message, size_t payloadLen,
239 const std::shared_ptr<session::Session>& session);
Tom Joseph78478a82017-01-26 14:24:29 +0530240
Tom Joseph3563f8f2017-05-08 15:42:54 +0530241/**
Tom Joseph75362832017-01-26 15:17:04 +0530242 * @brief Encrypt the plain text payload for the outgoing IPMI packet
243 *
244 * @param[in] message - IPMI Message populated for the outgoing packet
Lei YUce1f4fc2022-07-12 20:22:17 +0800245 * @param[in] session - session handle
Tom Joseph75362832017-01-26 15:17:04 +0530246 *
247 * @return on successful completion, return the encrypted payload
248 */
Lei YUce1f4fc2022-07-12 20:22:17 +0800249std::vector<uint8_t>
250 encryptPayload(std::shared_ptr<Message> message,
251 const std::shared_ptr<session::Session>& session);
Tom Joseph75362832017-01-26 15:17:04 +0530252
Tom Joseph4e57ada2016-08-10 06:51:12 -0500253} // namespace internal
254
255} // namespace ipmi20parser
256
Kirill Pakhomovde7dd5c2021-02-27 18:45:22 +0300257#ifdef RMCP_PING
258namespace asfparser
259{
260
261// ASF message fields for RMCP Ping message
262struct AsfMessagePing_t
263{
264 struct parser::RmcpHeader_t rmcp;
265
266 uint32_t iana;
267 uint8_t msgType;
268 uint8_t msgTag;
269 uint8_t reserved;
270 uint8_t dataLen;
271} __attribute__((packed));
272
273// ASF message fields for RMCP Pong message
274struct AsfMessagePong_t
275{
276 struct AsfMessagePing_t ping;
277
278 uint32_t iana;
279 uint32_t oemDefined;
280 uint8_t suppEntities;
281 uint8_t suppInteract;
282 uint32_t reserved1;
283 uint16_t reserved2;
284} __attribute__((packed));
285
286/**
287 * @brief Unflatten an incoming packet and prepare the ASF message
288 *
289 * @param[in] inPacket - Incoming ASF packet
290 *
291 * @return ASF message in the packet on success
292 */
293std::shared_ptr<Message> unflatten(std::vector<uint8_t>& inPacket);
294
295/**
296 * @brief Generate the ASF packet with the RMCP header
297 *
298 * @param[in] asfMsgTag - ASF Message Tag from Ping request
299 *
300 * @return ASF packet on success
301 */
302std::vector<uint8_t> flatten(uint8_t asfMsgTag);
303
304} // namespace asfparser
305#endif // RMCP_PING
306
Tom Joseph4e57ada2016-08-10 06:51:12 -0500307} // namespace message