blob: 33b53c17127783b17df366028c6256c2223dacd6 [file] [log] [blame]
Tom Joseph4e57ada2016-08-10 06:51:12 -05001#include "message_parsers.hpp"
2
Tom Joseph4e57ada2016-08-10 06:51:12 -05003#include "endian.hpp"
4#include "main.hpp"
5#include "message.hpp"
6#include "sessions_manager.hpp"
7
Vernon Mauery9e801a22018-10-12 13:20:49 -07008#include <memory>
9
Tom Joseph4e57ada2016-08-10 06:51:12 -050010namespace message
11{
12
13namespace parser
14{
15
Vernon Maueryd999ffc2018-10-25 09:16:05 -070016std::tuple<std::shared_ptr<Message>, SessionHeader>
Vernon Mauery9e801a22018-10-12 13:20:49 -070017 unflatten(std::vector<uint8_t>& inPacket)
Tom Joseph4e57ada2016-08-10 06:51:12 -050018{
19 // Check if the packet has atleast the size of the RMCP Header
Kirill Pakhomovde7dd5c2021-02-27 18:45:22 +030020 if (inPacket.size() < sizeof(RmcpHeader_t))
Tom Joseph4e57ada2016-08-10 06:51:12 -050021 {
22 throw std::runtime_error("RMCP Header missing");
23 }
24
Kirill Pakhomovde7dd5c2021-02-27 18:45:22 +030025 auto rmcpHeaderPtr = reinterpret_cast<RmcpHeader_t*>(inPacket.data());
Tom Joseph4e57ada2016-08-10 06:51:12 -050026
27 // Verify if the fields in the RMCP header conforms to the specification
28 if ((rmcpHeaderPtr->version != RMCP_VERSION) ||
29 (rmcpHeaderPtr->rmcpSeqNum != RMCP_SEQ) ||
Kirill Pakhomovde7dd5c2021-02-27 18:45:22 +030030 (rmcpHeaderPtr->classOfMsg < static_cast<uint8_t>(ClassOfMsg::ASF) &&
31 rmcpHeaderPtr->classOfMsg > static_cast<uint8_t>(ClassOfMsg::OEM)))
Tom Joseph4e57ada2016-08-10 06:51:12 -050032 {
33 throw std::runtime_error("RMCP Header is invalid");
34 }
35
Kirill Pakhomovde7dd5c2021-02-27 18:45:22 +030036 if (rmcpHeaderPtr->classOfMsg == static_cast<uint8_t>(ClassOfMsg::ASF))
37 {
38#ifndef RMCP_PING
39 throw std::runtime_error("RMCP Ping is not supported");
40#else
41 return std::make_tuple(asfparser::unflatten(inPacket),
42 SessionHeader::IPMI15);
43#endif // RMCP_PING
44 }
45
46 auto sessionHeaderPtr = reinterpret_cast<BasicHeader_t*>(inPacket.data());
47
Tom Joseph4e57ada2016-08-10 06:51:12 -050048 // Read the Session Header and invoke the parser corresponding to the
49 // header type
Kirill Pakhomovde7dd5c2021-02-27 18:45:22 +030050 switch (static_cast<SessionHeader>(sessionHeaderPtr->format.formatType))
Tom Joseph4e57ada2016-08-10 06:51:12 -050051 {
52 case SessionHeader::IPMI15:
53 {
54 return std::make_tuple(ipmi15parser::unflatten(inPacket),
55 SessionHeader::IPMI15);
56 }
57 case SessionHeader::IPMI20:
58 {
59 return std::make_tuple(ipmi20parser::unflatten(inPacket),
60 SessionHeader::IPMI20);
61 }
62 default:
63 {
64 throw std::runtime_error("Invalid Session Header");
65 }
66 }
67}
68
Lei YUa82e4d32022-07-13 10:03:20 +080069std::vector<uint8_t> flatten(const std::shared_ptr<Message>& outMessage,
Vernon Mauery224f36a2018-10-25 08:52:23 -070070 SessionHeader authType,
Lei YUa82e4d32022-07-13 10:03:20 +080071 const std::shared_ptr<session::Session>& session)
Tom Joseph4e57ada2016-08-10 06:51:12 -050072{
73 // Call the flatten routine based on the header type
74 switch (authType)
75 {
76 case SessionHeader::IPMI15:
77 {
78 return ipmi15parser::flatten(outMessage, session);
79 }
80 case SessionHeader::IPMI20:
81 {
82 return ipmi20parser::flatten(outMessage, session);
83 }
84 default:
85 {
86 return {};
87 }
88 }
89}
90
91} // namespace parser
92
93namespace ipmi15parser
94{
95
Vernon Maueryd999ffc2018-10-25 09:16:05 -070096std::shared_ptr<Message> unflatten(std::vector<uint8_t>& inPacket)
Tom Joseph4e57ada2016-08-10 06:51:12 -050097{
Tom Joseph4e57ada2016-08-10 06:51:12 -050098 if (inPacket.size() < sizeof(SessionHeader_t))
99 {
100 throw std::runtime_error("IPMI1.5 Session Header Missing");
101 }
102
Tom Joseph4e57ada2016-08-10 06:51:12 -0500103 auto header = reinterpret_cast<SessionHeader_t*>(inPacket.data());
104
Vernon Mauery779e7e12021-06-08 16:24:45 -0700105 uint32_t sessionID = endian::from_ipmi(header->sessId);
106 if (sessionID != session::sessionZero)
107 {
108 throw std::runtime_error("IPMI1.5 session packets are unsupported");
109 }
110
111 auto message = std::make_shared<Message>();
112
Tom Joseph4e57ada2016-08-10 06:51:12 -0500113 message->payloadType = PayloadType::IPMI;
Vernon Mauery779e7e12021-06-08 16:24:45 -0700114 message->bmcSessionID = session::sessionZero;
Tom Joseph6a560762017-01-10 15:30:28 +0530115 message->sessionSeqNum = endian::from_ipmi(header->sessSeqNum);
Tom Joseph4e57ada2016-08-10 06:51:12 -0500116 message->isPacketEncrypted = false;
117 message->isPacketAuthenticated = false;
Kirill Pakhomovde7dd5c2021-02-27 18:45:22 +0300118 message->rmcpMsgClass =
119 static_cast<ClassOfMsg>(header->base.rmcp.classOfMsg);
Tom Joseph4e57ada2016-08-10 06:51:12 -0500120
Zhikui Ren2b1edef2020-07-24 14:32:13 -0700121 // Confirm the number of data bytes received correlates to
122 // the packet length in the header
Vernon Mauerya71b1ba2021-06-08 15:53:46 -0700123 size_t payloadLen = header->payloadLength;
124 if ((payloadLen == 0) || (inPacket.size() < (sizeof(*header) + payloadLen)))
Zhikui Ren2b1edef2020-07-24 14:32:13 -0700125 {
126 throw std::runtime_error("Invalid data length");
127 }
128
Vernon Mauery9e801a22018-10-12 13:20:49 -0700129 (message->payload)
130 .assign(inPacket.data() + sizeof(SessionHeader_t),
131 inPacket.data() + sizeof(SessionHeader_t) + payloadLen);
Tom Joseph4e57ada2016-08-10 06:51:12 -0500132
133 return message;
134}
135
George Liube1470c2022-07-04 14:33:24 +0800136std::vector<uint8_t>
137 flatten(const std::shared_ptr<Message>& outMessage,
138 const std::shared_ptr<session::Session>& /* session */)
Tom Joseph4e57ada2016-08-10 06:51:12 -0500139{
140 std::vector<uint8_t> packet(sizeof(SessionHeader_t));
141
142 // Insert Session Header into the Packet
143 auto header = reinterpret_cast<SessionHeader_t*>(packet.data());
Kirill Pakhomovde7dd5c2021-02-27 18:45:22 +0300144 header->base.rmcp.version = parser::RMCP_VERSION;
145 header->base.rmcp.reserved = 0x00;
146 header->base.rmcp.rmcpSeqNum = parser::RMCP_SEQ;
147 header->base.rmcp.classOfMsg = static_cast<uint8_t>(ClassOfMsg::IPMI);
Tom Joseph4e57ada2016-08-10 06:51:12 -0500148 header->base.format.formatType =
149 static_cast<uint8_t>(parser::SessionHeader::IPMI15);
150 header->sessSeqNum = 0;
Vernon Maueryd999ffc2018-10-25 09:16:05 -0700151 header->sessId = endian::to_ipmi(outMessage->rcSessionID);
Tom Joseph4e57ada2016-08-10 06:51:12 -0500152
Vernon Maueryd999ffc2018-10-25 09:16:05 -0700153 header->payloadLength = static_cast<uint8_t>(outMessage->payload.size());
Tom Joseph4e57ada2016-08-10 06:51:12 -0500154
155 // Insert the Payload into the Packet
Vernon Maueryd999ffc2018-10-25 09:16:05 -0700156 packet.insert(packet.end(), outMessage->payload.begin(),
157 outMessage->payload.end());
Tom Joseph4e57ada2016-08-10 06:51:12 -0500158
159 // Insert the Session Trailer
160 packet.resize(packet.size() + sizeof(SessionTrailer_t));
Vernon Mauery9e801a22018-10-12 13:20:49 -0700161 auto trailer =
162 reinterpret_cast<SessionTrailer_t*>(packet.data() + packet.size());
Tom Joseph4e57ada2016-08-10 06:51:12 -0500163 trailer->legacyPad = 0x00;
164
165 return packet;
166}
167
168} // namespace ipmi15parser
169
170namespace ipmi20parser
171{
172
Vernon Maueryd999ffc2018-10-25 09:16:05 -0700173std::shared_ptr<Message> unflatten(std::vector<uint8_t>& inPacket)
Tom Joseph4e57ada2016-08-10 06:51:12 -0500174{
175 // Check if the packet has atleast the Session Header
176 if (inPacket.size() < sizeof(SessionHeader_t))
177 {
178 throw std::runtime_error("IPMI2.0 Session Header Missing");
179 }
180
Tom Joseph4e57ada2016-08-10 06:51:12 -0500181 auto header = reinterpret_cast<SessionHeader_t*>(inPacket.data());
182
Vernon Mauery1ab1c6b2021-06-08 15:54:41 -0700183 uint32_t sessionID = endian::from_ipmi(header->sessId);
184
Vernon Mauery2085ae02021-06-10 11:51:00 -0700185 auto session = session::Manager::get().getSession(sessionID);
Vernon Mauery1ab1c6b2021-06-08 15:54:41 -0700186 if (!session)
187 {
188 throw std::runtime_error("RMCP+ message from unknown session");
189 }
190
191 auto message = std::make_shared<Message>();
192
Vernon Mauery9e801a22018-10-12 13:20:49 -0700193 message->payloadType = static_cast<PayloadType>(header->payloadType & 0x3F);
Vernon Mauery1ab1c6b2021-06-08 15:54:41 -0700194 message->bmcSessionID = sessionID;
Tom Joseph6a560762017-01-10 15:30:28 +0530195 message->sessionSeqNum = endian::from_ipmi(header->sessSeqNum);
Tom Joseph4e57ada2016-08-10 06:51:12 -0500196 message->isPacketEncrypted =
197 ((header->payloadType & PAYLOAD_ENCRYPT_MASK) ? true : false);
198 message->isPacketAuthenticated =
199 ((header->payloadType & PAYLOAD_AUTH_MASK) ? true : false);
Kirill Pakhomovde7dd5c2021-02-27 18:45:22 +0300200 message->rmcpMsgClass =
201 static_cast<ClassOfMsg>(header->base.rmcp.classOfMsg);
Tom Joseph4e57ada2016-08-10 06:51:12 -0500202
Vernon Mauerya71b1ba2021-06-08 15:53:46 -0700203 // Confirm the number of data bytes received correlates to
204 // the packet length in the header
205 size_t payloadLen = endian::from_ipmi(header->payloadLength);
206 if ((payloadLen == 0) || (inPacket.size() < (sizeof(*header) + payloadLen)))
207 {
208 throw std::runtime_error("Invalid data length");
209 }
Tom Joseph4e57ada2016-08-10 06:51:12 -0500210
Patrick Williams099fb092023-05-10 07:50:31 -0500211 bool integrityMismatch = session->isIntegrityAlgoEnabled() &&
212 !message->isPacketAuthenticated;
213 bool encryptMismatch = session->isCryptAlgoEnabled() &&
214 !message->isPacketEncrypted;
Vernon Mauery1ab1c6b2021-06-08 15:54:41 -0700215
216 if (sessionID != session::sessionZero &&
217 (integrityMismatch || encryptMismatch))
218 {
219 throw std::runtime_error("unencrypted or unauthenticated message");
220 }
221
Tom Joseph5fa487c2017-01-20 12:42:39 +0530222 if (message->isPacketAuthenticated)
Tom Joseph64703f42017-01-10 17:03:48 +0530223 {
Lei YUce1f4fc2022-07-12 20:22:17 +0800224 if (!(internal::verifyPacketIntegrity(inPacket, message, payloadLen,
225 session)))
Tom Joseph64703f42017-01-10 17:03:48 +0530226 {
227 throw std::runtime_error("Packet Integrity check failed");
228 }
229 }
230
Tom Joseph78478a82017-01-26 14:24:29 +0530231 // Decrypt the payload if the payload is encrypted
232 if (message->isPacketEncrypted)
233 {
234 // Assign the decrypted payload to the IPMI Message
Patrick Williams099fb092023-05-10 07:50:31 -0500235 message->payload = internal::decryptPayload(inPacket, message,
236 payloadLen, session);
Tom Joseph78478a82017-01-26 14:24:29 +0530237 }
238 else
239 {
240 message->payload.assign(inPacket.begin() + sizeof(SessionHeader_t),
241 inPacket.begin() + sizeof(SessionHeader_t) +
Vernon Mauery9e801a22018-10-12 13:20:49 -0700242 payloadLen);
Tom Joseph78478a82017-01-26 14:24:29 +0530243 }
244
Tom Joseph4e57ada2016-08-10 06:51:12 -0500245 return message;
246}
247
Lei YUa82e4d32022-07-13 10:03:20 +0800248std::vector<uint8_t> flatten(const std::shared_ptr<Message>& outMessage,
249 const std::shared_ptr<session::Session>& session)
Tom Joseph4e57ada2016-08-10 06:51:12 -0500250{
251 std::vector<uint8_t> packet(sizeof(SessionHeader_t));
252
253 SessionHeader_t* header = reinterpret_cast<SessionHeader_t*>(packet.data());
Kirill Pakhomovde7dd5c2021-02-27 18:45:22 +0300254 header->base.rmcp.version = parser::RMCP_VERSION;
255 header->base.rmcp.reserved = 0x00;
256 header->base.rmcp.rmcpSeqNum = parser::RMCP_SEQ;
257 header->base.rmcp.classOfMsg = static_cast<uint8_t>(ClassOfMsg::IPMI);
Tom Joseph4e57ada2016-08-10 06:51:12 -0500258 header->base.format.formatType =
259 static_cast<uint8_t>(parser::SessionHeader::IPMI20);
Vernon Maueryd999ffc2018-10-25 09:16:05 -0700260 header->payloadType = static_cast<uint8_t>(outMessage->payloadType);
261 header->sessId = endian::to_ipmi(outMessage->rcSessionID);
Tom Joseph4e57ada2016-08-10 06:51:12 -0500262
263 // Add session sequence number
264 internal::addSequenceNumber(packet, session);
265
Tom Joseph1404bca2017-01-26 14:17:02 +0530266 size_t payloadLen = 0;
267
Tom Joseph75362832017-01-26 15:17:04 +0530268 // Encrypt the payload if needed
Vernon Maueryd999ffc2018-10-25 09:16:05 -0700269 if (outMessage->isPacketEncrypted)
Tom Joseph75362832017-01-26 15:17:04 +0530270 {
271 header->payloadType |= PAYLOAD_ENCRYPT_MASK;
Lei YUce1f4fc2022-07-12 20:22:17 +0800272 auto cipherPayload = internal::encryptPayload(outMessage, session);
Tom Joseph75362832017-01-26 15:17:04 +0530273 payloadLen = cipherPayload.size();
274 header->payloadLength = endian::to_ipmi<uint16_t>(cipherPayload.size());
275
276 // Insert the encrypted payload into the outgoing IPMI packet
277 packet.insert(packet.end(), cipherPayload.begin(), cipherPayload.end());
278 }
279 else
280 {
Vernon Mauery9e801a22018-10-12 13:20:49 -0700281 header->payloadLength =
Vernon Maueryd999ffc2018-10-25 09:16:05 -0700282 endian::to_ipmi<uint16_t>(outMessage->payload.size());
283 payloadLen = outMessage->payload.size();
Tom Joseph75362832017-01-26 15:17:04 +0530284
285 // Insert the Payload into the Packet
Vernon Maueryd999ffc2018-10-25 09:16:05 -0700286 packet.insert(packet.end(), outMessage->payload.begin(),
287 outMessage->payload.end());
Tom Joseph75362832017-01-26 15:17:04 +0530288 }
Tom Joseph4e57ada2016-08-10 06:51:12 -0500289
Vernon Maueryd999ffc2018-10-25 09:16:05 -0700290 if (outMessage->isPacketAuthenticated)
Tom Joseph64703f42017-01-10 17:03:48 +0530291 {
Tom Josephb882dbb2019-02-09 23:13:48 +0530292 header = reinterpret_cast<SessionHeader_t*>(packet.data());
293 header->payloadType |= PAYLOAD_AUTH_MASK;
Lei YUce1f4fc2022-07-12 20:22:17 +0800294 internal::addIntegrityData(packet, outMessage, payloadLen, session);
Tom Joseph64703f42017-01-10 17:03:48 +0530295 }
296
Tom Joseph4e57ada2016-08-10 06:51:12 -0500297 return packet;
298}
299
300namespace internal
301{
302
Vernon Mauery224f36a2018-10-25 08:52:23 -0700303void addSequenceNumber(std::vector<uint8_t>& packet,
Lei YUa82e4d32022-07-13 10:03:20 +0800304 const std::shared_ptr<session::Session>& session)
Tom Joseph4e57ada2016-08-10 06:51:12 -0500305{
306 SessionHeader_t* header = reinterpret_cast<SessionHeader_t*>(packet.data());
307
Suryakanth Sekarf8a34fc2019-06-12 20:59:18 +0530308 if (header->sessId == session::sessionZero)
Tom Joseph4e57ada2016-08-10 06:51:12 -0500309 {
310 header->sessSeqNum = 0x00;
311 }
312 else
313 {
Vernon Mauery224f36a2018-10-25 08:52:23 -0700314 auto seqNum = session->sequenceNums.increment();
Tom Joseph6a560762017-01-10 15:30:28 +0530315 header->sessSeqNum = endian::to_ipmi(seqNum);
Tom Joseph4e57ada2016-08-10 06:51:12 -0500316 }
317}
318
Tom Joseph64703f42017-01-10 17:03:48 +0530319bool verifyPacketIntegrity(const std::vector<uint8_t>& packet,
George Liube1470c2022-07-04 14:33:24 +0800320 const std::shared_ptr<Message>& /* message */,
Lei YUce1f4fc2022-07-12 20:22:17 +0800321 size_t payloadLen,
322 const std::shared_ptr<session::Session>& session)
Tom Joseph64703f42017-01-10 17:03:48 +0530323{
Tom Joseph64703f42017-01-10 17:03:48 +0530324 /*
325 * Padding bytes are added to cause the number of bytes in the data range
326 * covered by the AuthCode(Integrity Data) field to be a multiple of 4 bytes
327 * .If present each integrity Pad byte is set to FFh. The following logic
328 * calculates the number of padding bytes added in the IPMI packet.
329 */
Tom Joseph5a2d3ce2017-02-01 20:18:37 +0530330 auto paddingLen = 4 - ((payloadLen + 2) & 3);
Tom Joseph64703f42017-01-10 17:03:48 +0530331
332 auto sessTrailerPos = sizeof(SessionHeader_t) + payloadLen + paddingLen;
333
Zhikui Ren2b1edef2020-07-24 14:32:13 -0700334 // verify packet size includes trailer struct starts at sessTrailerPos
335 if (packet.size() < (sessTrailerPos + sizeof(SessionTrailer_t)))
336 {
337 return false;
338 }
339
Vernon Mauery9e801a22018-10-12 13:20:49 -0700340 auto trailer = reinterpret_cast<const SessionTrailer_t*>(packet.data() +
341 sessTrailerPos);
Tom Joseph64703f42017-01-10 17:03:48 +0530342
343 // Check trailer->padLength against paddingLen, both should match up,
344 // return false if the lengths don't match
Tom Joseph5fa487c2017-01-20 12:42:39 +0530345 if (trailer->padLength != paddingLen)
Tom Joseph64703f42017-01-10 17:03:48 +0530346 {
347 return false;
348 }
349
Tom Joseph64703f42017-01-10 17:03:48 +0530350 auto integrityAlgo = session->getIntegrityAlgo();
351
352 // Check if Integrity data length is as expected, check integrity data
353 // length is same as the length expected for the Integrity Algorithm that
354 // was negotiated during the session open process.
Tom Joseph5fa487c2017-01-20 12:42:39 +0530355 if ((packet.size() - sessTrailerPos - sizeof(SessionTrailer_t)) !=
Vernon Mauery9e801a22018-10-12 13:20:49 -0700356 integrityAlgo->authCodeLength)
Tom Joseph64703f42017-01-10 17:03:48 +0530357 {
358 return false;
359 }
360
361 auto integrityIter = packet.cbegin();
362 std::advance(integrityIter, sessTrailerPos + sizeof(SessionTrailer_t));
363
364 // The integrity data is calculated from the AuthType/Format field up to and
365 // including the field that immediately precedes the AuthCode field itself.
366 size_t length = packet.size() - integrityAlgo->authCodeLength -
367 message::parser::RMCP_SESSION_HEADER_SIZE;
368
George Liu198b0f82022-08-04 20:22:48 +0800369 return integrityAlgo->verifyIntegrityData(packet, length, integrityIter,
370 packet.cend());
Tom Joseph64703f42017-01-10 17:03:48 +0530371}
372
Vernon Maueryd999ffc2018-10-25 09:16:05 -0700373void addIntegrityData(std::vector<uint8_t>& packet,
George Liube1470c2022-07-04 14:33:24 +0800374 const std::shared_ptr<Message>& /* message */,
Lei YUa82e4d32022-07-13 10:03:20 +0800375 size_t payloadLen,
Lei YUce1f4fc2022-07-12 20:22:17 +0800376 const std::shared_ptr<session::Session>& session)
Tom Joseph64703f42017-01-10 17:03:48 +0530377{
Tom Joseph64703f42017-01-10 17:03:48 +0530378 // The following logic calculates the number of padding bytes to be added to
379 // IPMI packet. If needed each integrity Pad byte is set to FFh.
Tom Joseph5a2d3ce2017-02-01 20:18:37 +0530380 auto paddingLen = 4 - ((payloadLen + 2) & 3);
Tom Joseph64703f42017-01-10 17:03:48 +0530381 packet.insert(packet.end(), paddingLen, 0xFF);
382
383 packet.resize(packet.size() + sizeof(SessionTrailer_t));
384
Vernon Mauery9e801a22018-10-12 13:20:49 -0700385 auto trailer = reinterpret_cast<SessionTrailer_t*>(
386 packet.data() + packet.size() - sizeof(SessionTrailer_t));
Tom Joseph64703f42017-01-10 17:03:48 +0530387
388 trailer->padLength = paddingLen;
389 trailer->nextHeader = parser::RMCP_MESSAGE_CLASS_IPMI;
390
Vernon Mauery9e801a22018-10-12 13:20:49 -0700391 auto integrityData =
392 session->getIntegrityAlgo()->generateIntegrityData(packet);
Tom Joseph64703f42017-01-10 17:03:48 +0530393
394 packet.insert(packet.end(), integrityData.begin(), integrityData.end());
395}
396
Lei YUce1f4fc2022-07-12 20:22:17 +0800397std::vector<uint8_t>
398 decryptPayload(const std::vector<uint8_t>& packet,
George Liube1470c2022-07-04 14:33:24 +0800399 const std::shared_ptr<Message>& /* message */,
400 size_t payloadLen,
Lei YUce1f4fc2022-07-12 20:22:17 +0800401 const std::shared_ptr<session::Session>& session)
Tom Joseph78478a82017-01-26 14:24:29 +0530402{
Vernon Mauery9e801a22018-10-12 13:20:49 -0700403 return session->getCryptAlgo()->decryptPayload(
404 packet, sizeof(SessionHeader_t), payloadLen);
Tom Joseph78478a82017-01-26 14:24:29 +0530405}
406
Lei YUce1f4fc2022-07-12 20:22:17 +0800407std::vector<uint8_t>
Lei YUa82e4d32022-07-13 10:03:20 +0800408 encryptPayload(const std::shared_ptr<Message>& message,
Lei YUce1f4fc2022-07-12 20:22:17 +0800409 const std::shared_ptr<session::Session>& session)
Tom Joseph75362832017-01-26 15:17:04 +0530410{
Vernon Maueryd999ffc2018-10-25 09:16:05 -0700411 return session->getCryptAlgo()->encryptPayload(message->payload);
Tom Joseph75362832017-01-26 15:17:04 +0530412}
413
Tom Joseph4e57ada2016-08-10 06:51:12 -0500414} // namespace internal
415
416} // namespace ipmi20parser
417
Kirill Pakhomovde7dd5c2021-02-27 18:45:22 +0300418#ifdef RMCP_PING
419namespace asfparser
420{
421std::shared_ptr<Message> unflatten(std::vector<uint8_t>& inPacket)
422{
423 auto message = std::make_shared<Message>();
424
425 auto header = reinterpret_cast<AsfMessagePing_t*>(inPacket.data());
426
427 message->payloadType = PayloadType::IPMI;
428 message->rmcpMsgClass = ClassOfMsg::ASF;
429 message->asfMsgTag = header->msgTag;
430
431 return message;
432}
433
434std::vector<uint8_t> flatten(uint8_t asfMsgTag)
435{
436 std::vector<uint8_t> packet(sizeof(AsfMessagePong_t));
437
438 // Insert RMCP header into the Packet
439 auto header = reinterpret_cast<AsfMessagePong_t*>(packet.data());
440 header->ping.rmcp.version = parser::RMCP_VERSION;
441 header->ping.rmcp.reserved = 0x00;
442 header->ping.rmcp.rmcpSeqNum = parser::RMCP_SEQ;
443 header->ping.rmcp.classOfMsg = static_cast<uint8_t>(ClassOfMsg::ASF);
444
445 // No OEM-specific capabilities exist, therefore the second
446 // IANA Enterprise Number contains the same IANA(4542)
447 header->ping.iana = header->iana = endian::to_ipmi(parser::ASF_IANA);
448 header->ping.msgType = static_cast<uint8_t>(RmcpMsgType::PONG);
449 header->ping.msgTag = asfMsgTag;
450 header->ping.reserved = 0x00;
451 header->ping.dataLen =
452 parser::RMCP_ASF_PONG_DATA_LEN; // as per spec 13.2.4,
453
454 header->iana = parser::ASF_IANA;
455 header->oemDefined = 0x00;
456 header->suppEntities = parser::ASF_SUPP_ENT;
457 header->suppInteract = parser::ASF_SUPP_INT;
458 header->reserved1 = 0x00;
459 header->reserved2 = 0x00;
460
461 return packet;
462}
463
464} // namespace asfparser
465#endif // RMCP_PING
466
Tom Joseph4e57ada2016-08-10 06:51:12 -0500467} // namespace message