blob: 7b8d8329ced1c0f5dae918e795e50d46488e8e5a [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
Vernon Maueryd999ffc2018-10-25 09:16:05 -070069std::vector<uint8_t> flatten(std::shared_ptr<Message> outMessage,
Vernon Mauery224f36a2018-10-25 08:52:23 -070070 SessionHeader authType,
71 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
Vernon Maueryd999ffc2018-10-25 09:16:05 -0700136std::vector<uint8_t> flatten(std::shared_ptr<Message> outMessage,
Vernon Mauery224f36a2018-10-25 08:52:23 -0700137 std::shared_ptr<session::Session> session)
Tom Joseph4e57ada2016-08-10 06:51:12 -0500138{
139 std::vector<uint8_t> packet(sizeof(SessionHeader_t));
140
141 // Insert Session Header into the Packet
142 auto header = reinterpret_cast<SessionHeader_t*>(packet.data());
Kirill Pakhomovde7dd5c2021-02-27 18:45:22 +0300143 header->base.rmcp.version = parser::RMCP_VERSION;
144 header->base.rmcp.reserved = 0x00;
145 header->base.rmcp.rmcpSeqNum = parser::RMCP_SEQ;
146 header->base.rmcp.classOfMsg = static_cast<uint8_t>(ClassOfMsg::IPMI);
Tom Joseph4e57ada2016-08-10 06:51:12 -0500147 header->base.format.formatType =
148 static_cast<uint8_t>(parser::SessionHeader::IPMI15);
149 header->sessSeqNum = 0;
Vernon Maueryd999ffc2018-10-25 09:16:05 -0700150 header->sessId = endian::to_ipmi(outMessage->rcSessionID);
Tom Joseph4e57ada2016-08-10 06:51:12 -0500151
Vernon Maueryd999ffc2018-10-25 09:16:05 -0700152 header->payloadLength = static_cast<uint8_t>(outMessage->payload.size());
Tom Joseph4e57ada2016-08-10 06:51:12 -0500153
154 // Insert the Payload into the Packet
Vernon Maueryd999ffc2018-10-25 09:16:05 -0700155 packet.insert(packet.end(), outMessage->payload.begin(),
156 outMessage->payload.end());
Tom Joseph4e57ada2016-08-10 06:51:12 -0500157
158 // Insert the Session Trailer
159 packet.resize(packet.size() + sizeof(SessionTrailer_t));
Vernon Mauery9e801a22018-10-12 13:20:49 -0700160 auto trailer =
161 reinterpret_cast<SessionTrailer_t*>(packet.data() + packet.size());
Tom Joseph4e57ada2016-08-10 06:51:12 -0500162 trailer->legacyPad = 0x00;
163
164 return packet;
165}
166
167} // namespace ipmi15parser
168
169namespace ipmi20parser
170{
171
Vernon Maueryd999ffc2018-10-25 09:16:05 -0700172std::shared_ptr<Message> unflatten(std::vector<uint8_t>& inPacket)
Tom Joseph4e57ada2016-08-10 06:51:12 -0500173{
174 // Check if the packet has atleast the Session Header
175 if (inPacket.size() < sizeof(SessionHeader_t))
176 {
177 throw std::runtime_error("IPMI2.0 Session Header Missing");
178 }
179
Tom Joseph4e57ada2016-08-10 06:51:12 -0500180 auto header = reinterpret_cast<SessionHeader_t*>(inPacket.data());
181
Vernon Mauery1ab1c6b2021-06-08 15:54:41 -0700182 uint32_t sessionID = endian::from_ipmi(header->sessId);
183
184 auto session =
185 std::get<session::Manager&>(singletonPool).getSession(sessionID);
186 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
Vernon Mauery1ab1c6b2021-06-08 15:54:41 -0700211 bool integrityMismatch =
212 session->isIntegrityAlgoEnabled() && !message->isPacketAuthenticated;
213 bool encryptMismatch =
214 session->isCryptAlgoEnabled() && !message->isPacketEncrypted;
215
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 {
Vernon Maueryd999ffc2018-10-25 09:16:05 -0700224 if (!(internal::verifyPacketIntegrity(inPacket, message, payloadLen)))
Tom Joseph64703f42017-01-10 17:03:48 +0530225 {
226 throw std::runtime_error("Packet Integrity check failed");
227 }
228 }
229
Tom Joseph78478a82017-01-26 14:24:29 +0530230 // Decrypt the payload if the payload is encrypted
231 if (message->isPacketEncrypted)
232 {
233 // Assign the decrypted payload to the IPMI Message
Vernon Mauery9e801a22018-10-12 13:20:49 -0700234 message->payload =
Vernon Maueryd999ffc2018-10-25 09:16:05 -0700235 internal::decryptPayload(inPacket, message, payloadLen);
Tom Joseph78478a82017-01-26 14:24:29 +0530236 }
237 else
238 {
239 message->payload.assign(inPacket.begin() + sizeof(SessionHeader_t),
240 inPacket.begin() + sizeof(SessionHeader_t) +
Vernon Mauery9e801a22018-10-12 13:20:49 -0700241 payloadLen);
Tom Joseph78478a82017-01-26 14:24:29 +0530242 }
243
Tom Joseph4e57ada2016-08-10 06:51:12 -0500244 return message;
245}
246
Vernon Maueryd999ffc2018-10-25 09:16:05 -0700247std::vector<uint8_t> flatten(std::shared_ptr<Message> outMessage,
Vernon Mauery224f36a2018-10-25 08:52:23 -0700248 std::shared_ptr<session::Session> session)
Tom Joseph4e57ada2016-08-10 06:51:12 -0500249{
250 std::vector<uint8_t> packet(sizeof(SessionHeader_t));
251
252 SessionHeader_t* header = reinterpret_cast<SessionHeader_t*>(packet.data());
Kirill Pakhomovde7dd5c2021-02-27 18:45:22 +0300253 header->base.rmcp.version = parser::RMCP_VERSION;
254 header->base.rmcp.reserved = 0x00;
255 header->base.rmcp.rmcpSeqNum = parser::RMCP_SEQ;
256 header->base.rmcp.classOfMsg = static_cast<uint8_t>(ClassOfMsg::IPMI);
Tom Joseph4e57ada2016-08-10 06:51:12 -0500257 header->base.format.formatType =
258 static_cast<uint8_t>(parser::SessionHeader::IPMI20);
Vernon Maueryd999ffc2018-10-25 09:16:05 -0700259 header->payloadType = static_cast<uint8_t>(outMessage->payloadType);
260 header->sessId = endian::to_ipmi(outMessage->rcSessionID);
Tom Joseph4e57ada2016-08-10 06:51:12 -0500261
262 // Add session sequence number
263 internal::addSequenceNumber(packet, session);
264
Tom Joseph1404bca2017-01-26 14:17:02 +0530265 size_t payloadLen = 0;
266
Tom Joseph75362832017-01-26 15:17:04 +0530267 // Encrypt the payload if needed
Vernon Maueryd999ffc2018-10-25 09:16:05 -0700268 if (outMessage->isPacketEncrypted)
Tom Joseph75362832017-01-26 15:17:04 +0530269 {
270 header->payloadType |= PAYLOAD_ENCRYPT_MASK;
271 auto cipherPayload = internal::encryptPayload(outMessage);
272 payloadLen = cipherPayload.size();
273 header->payloadLength = endian::to_ipmi<uint16_t>(cipherPayload.size());
274
275 // Insert the encrypted payload into the outgoing IPMI packet
276 packet.insert(packet.end(), cipherPayload.begin(), cipherPayload.end());
277 }
278 else
279 {
Vernon Mauery9e801a22018-10-12 13:20:49 -0700280 header->payloadLength =
Vernon Maueryd999ffc2018-10-25 09:16:05 -0700281 endian::to_ipmi<uint16_t>(outMessage->payload.size());
282 payloadLen = outMessage->payload.size();
Tom Joseph75362832017-01-26 15:17:04 +0530283
284 // Insert the Payload into the Packet
Vernon Maueryd999ffc2018-10-25 09:16:05 -0700285 packet.insert(packet.end(), outMessage->payload.begin(),
286 outMessage->payload.end());
Tom Joseph75362832017-01-26 15:17:04 +0530287 }
Tom Joseph4e57ada2016-08-10 06:51:12 -0500288
Vernon Maueryd999ffc2018-10-25 09:16:05 -0700289 if (outMessage->isPacketAuthenticated)
Tom Joseph64703f42017-01-10 17:03:48 +0530290 {
Tom Josephb882dbb2019-02-09 23:13:48 +0530291 header = reinterpret_cast<SessionHeader_t*>(packet.data());
292 header->payloadType |= PAYLOAD_AUTH_MASK;
Tom Joseph1404bca2017-01-26 14:17:02 +0530293 internal::addIntegrityData(packet, outMessage, payloadLen);
Tom Joseph64703f42017-01-10 17:03:48 +0530294 }
295
Tom Joseph4e57ada2016-08-10 06:51:12 -0500296 return packet;
297}
298
299namespace internal
300{
301
Vernon Mauery224f36a2018-10-25 08:52:23 -0700302void addSequenceNumber(std::vector<uint8_t>& packet,
303 std::shared_ptr<session::Session> session)
Tom Joseph4e57ada2016-08-10 06:51:12 -0500304{
305 SessionHeader_t* header = reinterpret_cast<SessionHeader_t*>(packet.data());
306
Suryakanth Sekarf8a34fc2019-06-12 20:59:18 +0530307 if (header->sessId == session::sessionZero)
Tom Joseph4e57ada2016-08-10 06:51:12 -0500308 {
309 header->sessSeqNum = 0x00;
310 }
311 else
312 {
Vernon Mauery224f36a2018-10-25 08:52:23 -0700313 auto seqNum = session->sequenceNums.increment();
Tom Joseph6a560762017-01-10 15:30:28 +0530314 header->sessSeqNum = endian::to_ipmi(seqNum);
Tom Joseph4e57ada2016-08-10 06:51:12 -0500315 }
316}
317
Tom Joseph64703f42017-01-10 17:03:48 +0530318bool verifyPacketIntegrity(const std::vector<uint8_t>& packet,
Vernon Maueryd999ffc2018-10-25 09:16:05 -0700319 const std::shared_ptr<Message> message,
320 size_t payloadLen)
Tom Joseph64703f42017-01-10 17:03:48 +0530321{
Tom Joseph64703f42017-01-10 17:03:48 +0530322 /*
323 * Padding bytes are added to cause the number of bytes in the data range
324 * covered by the AuthCode(Integrity Data) field to be a multiple of 4 bytes
325 * .If present each integrity Pad byte is set to FFh. The following logic
326 * calculates the number of padding bytes added in the IPMI packet.
327 */
Tom Joseph5a2d3ce2017-02-01 20:18:37 +0530328 auto paddingLen = 4 - ((payloadLen + 2) & 3);
Tom Joseph64703f42017-01-10 17:03:48 +0530329
330 auto sessTrailerPos = sizeof(SessionHeader_t) + payloadLen + paddingLen;
331
Zhikui Ren2b1edef2020-07-24 14:32:13 -0700332 // verify packet size includes trailer struct starts at sessTrailerPos
333 if (packet.size() < (sessTrailerPos + sizeof(SessionTrailer_t)))
334 {
335 return false;
336 }
337
Vernon Mauery9e801a22018-10-12 13:20:49 -0700338 auto trailer = reinterpret_cast<const SessionTrailer_t*>(packet.data() +
339 sessTrailerPos);
Tom Joseph64703f42017-01-10 17:03:48 +0530340
341 // Check trailer->padLength against paddingLen, both should match up,
342 // return false if the lengths don't match
Tom Joseph5fa487c2017-01-20 12:42:39 +0530343 if (trailer->padLength != paddingLen)
Tom Joseph64703f42017-01-10 17:03:48 +0530344 {
345 return false;
346 }
347
Vernon Maueryae1fda42018-10-15 12:55:34 -0700348 auto session = std::get<session::Manager&>(singletonPool)
Vernon Maueryd999ffc2018-10-25 09:16:05 -0700349 .getSession(message->bmcSessionID);
Tom Joseph64703f42017-01-10 17:03:48 +0530350
351 auto integrityAlgo = session->getIntegrityAlgo();
352
353 // Check if Integrity data length is as expected, check integrity data
354 // length is same as the length expected for the Integrity Algorithm that
355 // was negotiated during the session open process.
Tom Joseph5fa487c2017-01-20 12:42:39 +0530356 if ((packet.size() - sessTrailerPos - sizeof(SessionTrailer_t)) !=
Vernon Mauery9e801a22018-10-12 13:20:49 -0700357 integrityAlgo->authCodeLength)
Tom Joseph64703f42017-01-10 17:03:48 +0530358 {
359 return false;
360 }
361
362 auto integrityIter = packet.cbegin();
363 std::advance(integrityIter, sessTrailerPos + sizeof(SessionTrailer_t));
364
365 // The integrity data is calculated from the AuthType/Format field up to and
366 // including the field that immediately precedes the AuthCode field itself.
367 size_t length = packet.size() - integrityAlgo->authCodeLength -
368 message::parser::RMCP_SESSION_HEADER_SIZE;
369
370 return integrityAlgo->verifyIntegrityData(packet, length, integrityIter);
371}
372
Vernon Maueryd999ffc2018-10-25 09:16:05 -0700373void addIntegrityData(std::vector<uint8_t>& packet,
374 const std::shared_ptr<Message> message, size_t payloadLen)
Tom Joseph64703f42017-01-10 17:03:48 +0530375{
Tom Joseph64703f42017-01-10 17:03:48 +0530376 // The following logic calculates the number of padding bytes to be added to
377 // IPMI packet. If needed each integrity Pad byte is set to FFh.
Tom Joseph5a2d3ce2017-02-01 20:18:37 +0530378 auto paddingLen = 4 - ((payloadLen + 2) & 3);
Tom Joseph64703f42017-01-10 17:03:48 +0530379 packet.insert(packet.end(), paddingLen, 0xFF);
380
381 packet.resize(packet.size() + sizeof(SessionTrailer_t));
382
Vernon Mauery9e801a22018-10-12 13:20:49 -0700383 auto trailer = reinterpret_cast<SessionTrailer_t*>(
384 packet.data() + packet.size() - sizeof(SessionTrailer_t));
Tom Joseph64703f42017-01-10 17:03:48 +0530385
386 trailer->padLength = paddingLen;
387 trailer->nextHeader = parser::RMCP_MESSAGE_CLASS_IPMI;
388
Vernon Maueryae1fda42018-10-15 12:55:34 -0700389 auto session = std::get<session::Manager&>(singletonPool)
Vernon Maueryd999ffc2018-10-25 09:16:05 -0700390 .getSession(message->bmcSessionID);
Tom Joseph64703f42017-01-10 17:03:48 +0530391
Vernon Mauery9e801a22018-10-12 13:20:49 -0700392 auto integrityData =
393 session->getIntegrityAlgo()->generateIntegrityData(packet);
Tom Joseph64703f42017-01-10 17:03:48 +0530394
395 packet.insert(packet.end(), integrityData.begin(), integrityData.end());
396}
397
Tom Joseph78478a82017-01-26 14:24:29 +0530398std::vector<uint8_t> decryptPayload(const std::vector<uint8_t>& packet,
Vernon Maueryd999ffc2018-10-25 09:16:05 -0700399 const std::shared_ptr<Message> message,
400 size_t payloadLen)
Tom Joseph78478a82017-01-26 14:24:29 +0530401{
Vernon Maueryae1fda42018-10-15 12:55:34 -0700402 auto session = std::get<session::Manager&>(singletonPool)
Vernon Maueryd999ffc2018-10-25 09:16:05 -0700403 .getSession(message->bmcSessionID);
Tom Joseph78478a82017-01-26 14:24:29 +0530404
Vernon Mauery9e801a22018-10-12 13:20:49 -0700405 return session->getCryptAlgo()->decryptPayload(
406 packet, sizeof(SessionHeader_t), payloadLen);
Tom Joseph78478a82017-01-26 14:24:29 +0530407}
408
Vernon Maueryd999ffc2018-10-25 09:16:05 -0700409std::vector<uint8_t> encryptPayload(std::shared_ptr<Message> message)
Tom Joseph75362832017-01-26 15:17:04 +0530410{
Vernon Maueryae1fda42018-10-15 12:55:34 -0700411 auto session = std::get<session::Manager&>(singletonPool)
Vernon Maueryd999ffc2018-10-25 09:16:05 -0700412 .getSession(message->bmcSessionID);
Tom Joseph75362832017-01-26 15:17:04 +0530413
Vernon Maueryd999ffc2018-10-25 09:16:05 -0700414 return session->getCryptAlgo()->encryptPayload(message->payload);
Tom Joseph75362832017-01-26 15:17:04 +0530415}
416
Tom Joseph4e57ada2016-08-10 06:51:12 -0500417} // namespace internal
418
419} // namespace ipmi20parser
420
Kirill Pakhomovde7dd5c2021-02-27 18:45:22 +0300421#ifdef RMCP_PING
422namespace asfparser
423{
424std::shared_ptr<Message> unflatten(std::vector<uint8_t>& inPacket)
425{
426 auto message = std::make_shared<Message>();
427
428 auto header = reinterpret_cast<AsfMessagePing_t*>(inPacket.data());
429
430 message->payloadType = PayloadType::IPMI;
431 message->rmcpMsgClass = ClassOfMsg::ASF;
432 message->asfMsgTag = header->msgTag;
433
434 return message;
435}
436
437std::vector<uint8_t> flatten(uint8_t asfMsgTag)
438{
439 std::vector<uint8_t> packet(sizeof(AsfMessagePong_t));
440
441 // Insert RMCP header into the Packet
442 auto header = reinterpret_cast<AsfMessagePong_t*>(packet.data());
443 header->ping.rmcp.version = parser::RMCP_VERSION;
444 header->ping.rmcp.reserved = 0x00;
445 header->ping.rmcp.rmcpSeqNum = parser::RMCP_SEQ;
446 header->ping.rmcp.classOfMsg = static_cast<uint8_t>(ClassOfMsg::ASF);
447
448 // No OEM-specific capabilities exist, therefore the second
449 // IANA Enterprise Number contains the same IANA(4542)
450 header->ping.iana = header->iana = endian::to_ipmi(parser::ASF_IANA);
451 header->ping.msgType = static_cast<uint8_t>(RmcpMsgType::PONG);
452 header->ping.msgTag = asfMsgTag;
453 header->ping.reserved = 0x00;
454 header->ping.dataLen =
455 parser::RMCP_ASF_PONG_DATA_LEN; // as per spec 13.2.4,
456
457 header->iana = parser::ASF_IANA;
458 header->oemDefined = 0x00;
459 header->suppEntities = parser::ASF_SUPP_ENT;
460 header->suppInteract = parser::ASF_SUPP_INT;
461 header->reserved1 = 0x00;
462 header->reserved2 = 0x00;
463
464 return packet;
465}
466
467} // namespace asfparser
468#endif // RMCP_PING
469
Tom Joseph4e57ada2016-08-10 06:51:12 -0500470} // namespace message