blob: d6069cc2cafb4dbf6867fe1d1133b61773b43d25 [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 */
Lei YUa82e4d32022-07-13 10:03:20 +080097std::vector<uint8_t> flatten(const std::shared_ptr<Message>& outMessage,
Vernon Mauery224f36a2018-10-25 08:52:23 -070098 SessionHeader authType,
Lei YUa82e4d32022-07-13 10:03:20 +080099 const 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 */
Lei YUa82e4d32022-07-13 10:03:20 +0800137std::vector<uint8_t> flatten(const std::shared_ptr<Message>& outMessage,
138 const 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 */
Lei YUa82e4d32022-07-13 10:03:20 +0800185std::vector<uint8_t> flatten(const std::shared_ptr<Message>& outMessage,
186 const 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,
Lei YUa82e4d32022-07-13 10:03:20 +0800199 const 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,
Lei YUa82e4d32022-07-13 10:03:20 +0800211 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 YUa82e4d32022-07-13 10:03:20 +0800223 const std::shared_ptr<Message>& message,
224 size_t payloadLen,
Lei YUce1f4fc2022-07-12 20:22:17 +0800225 const std::shared_ptr<session::Session>& session);
Tom Joseph64703f42017-01-10 17:03:48 +0530226
Tom Joseph3563f8f2017-05-08 15:42:54 +0530227/**
Tom Joseph78478a82017-01-26 14:24:29 +0530228 * @brief Decrypt the encrypted payload in the incoming IPMI packet
229 *
230 * @param[in] packet - Incoming IPMI packet
231 * @param[in] message - IPMI Message populated from the incoming packet
232 * @param[in] payloadLen - Length of encrypted IPMI payload
Lei YUce1f4fc2022-07-12 20:22:17 +0800233 * @param[in] session - session handle
Tom Joseph78478a82017-01-26 14:24:29 +0530234 *
235 * @return on successful completion, return the plain text payload
236 */
Lei YUce1f4fc2022-07-12 20:22:17 +0800237std::vector<uint8_t>
238 decryptPayload(const std::vector<uint8_t>& packet,
Lei YUa82e4d32022-07-13 10:03:20 +0800239 const std::shared_ptr<Message>& message, size_t payloadLen,
Lei YUce1f4fc2022-07-12 20:22:17 +0800240 const std::shared_ptr<session::Session>& session);
Tom Joseph78478a82017-01-26 14:24:29 +0530241
Tom Joseph3563f8f2017-05-08 15:42:54 +0530242/**
Tom Joseph75362832017-01-26 15:17:04 +0530243 * @brief Encrypt the plain text payload for the outgoing IPMI packet
244 *
245 * @param[in] message - IPMI Message populated for the outgoing packet
Lei YUce1f4fc2022-07-12 20:22:17 +0800246 * @param[in] session - session handle
Tom Joseph75362832017-01-26 15:17:04 +0530247 *
248 * @return on successful completion, return the encrypted payload
249 */
Lei YUce1f4fc2022-07-12 20:22:17 +0800250std::vector<uint8_t>
Lei YUa82e4d32022-07-13 10:03:20 +0800251 encryptPayload(const std::shared_ptr<Message>& message,
Lei YUce1f4fc2022-07-12 20:22:17 +0800252 const std::shared_ptr<session::Session>& session);
Tom Joseph75362832017-01-26 15:17:04 +0530253
Tom Joseph4e57ada2016-08-10 06:51:12 -0500254} // namespace internal
255
256} // namespace ipmi20parser
257
Kirill Pakhomovde7dd5c2021-02-27 18:45:22 +0300258#ifdef RMCP_PING
259namespace asfparser
260{
261
262// ASF message fields for RMCP Ping message
263struct AsfMessagePing_t
264{
265 struct parser::RmcpHeader_t rmcp;
266
267 uint32_t iana;
268 uint8_t msgType;
269 uint8_t msgTag;
270 uint8_t reserved;
271 uint8_t dataLen;
272} __attribute__((packed));
273
274// ASF message fields for RMCP Pong message
275struct AsfMessagePong_t
276{
277 struct AsfMessagePing_t ping;
278
279 uint32_t iana;
280 uint32_t oemDefined;
281 uint8_t suppEntities;
282 uint8_t suppInteract;
283 uint32_t reserved1;
284 uint16_t reserved2;
285} __attribute__((packed));
286
287/**
288 * @brief Unflatten an incoming packet and prepare the ASF message
289 *
290 * @param[in] inPacket - Incoming ASF packet
291 *
292 * @return ASF message in the packet on success
293 */
294std::shared_ptr<Message> unflatten(std::vector<uint8_t>& inPacket);
295
296/**
297 * @brief Generate the ASF packet with the RMCP header
298 *
299 * @param[in] asfMsgTag - ASF Message Tag from Ping request
300 *
301 * @return ASF packet on success
302 */
303std::vector<uint8_t> flatten(uint8_t asfMsgTag);
304
305} // namespace asfparser
306#endif // RMCP_PING
307
Tom Joseph4e57ada2016-08-10 06:51:12 -0500308} // namespace message