blob: 0dae43bbfd8d53d42ae3beaa46a3ac67d33ac6ce [file] [log] [blame]
Tom Joseph4e57ada2016-08-10 06:51:12 -05001#pragma once
2
3#include "message.hpp"
4#include "session.hpp"
5
6namespace message
7{
8
9namespace parser
10{
11
12constexpr size_t RMCP_VERSION = 6;
13
14// RMCP Messages with class=IPMI should be sent with an RMCP Sequence
15// Number of FFh to indicate that an RMCP ACK message should not be
16// generated by the message receiver.
17constexpr size_t RMCP_SEQ = 0xFF;
18
19// RMCP Message Class 7h is for IPMI
20constexpr size_t RMCP_MESSAGE_CLASS_IPMI = 7;
21
Tom Joseph64703f42017-01-10 17:03:48 +053022// RMCP Session Header Size
23constexpr size_t RMCP_SESSION_HEADER_SIZE = 4;
24
Tom Joseph1efcb492017-01-31 16:56:47 +053025// Maximum payload size
26constexpr size_t MAX_PAYLOAD_SIZE = 255;
27
Tom Joseph4e57ada2016-08-10 06:51:12 -050028enum class SessionHeader
29{
30 IPMI15 = 0x00,
31 IPMI20 = 0x06,
32 INVALID = 0xFF,
33};
34
35struct BasicHeader_t
36{
37 // RMCP Header
38 uint8_t version;
39 uint8_t reserved;
40 uint8_t rmcpSeqNum;
41 uint8_t classOfMsg;
42
43 // IPMI partial session header
44 union
45 {
Vernon Mauery9e801a22018-10-12 13:20:49 -070046 uint8_t reserved1 : 4;
47 uint8_t authType : 4;
Tom Joseph4e57ada2016-08-10 06:51:12 -050048 uint8_t formatType;
49 } format;
50} __attribute__((packed));
51
Tom Joseph3563f8f2017-05-08 15:42:54 +053052/**
Tom Joseph4e57ada2016-08-10 06:51:12 -050053 * @brief Unflatten an incoming packet and prepare the IPMI message
54 *
55 * @param[in] inPacket - Incoming IPMI packet
56 *
57 * @return A tuple with IPMI message and the session header type to sent the
58 * response packet. In case of success incoming message and session
59 * header type. In case of failure nullptr and session header type
60 * would be invalid.
61 */
Vernon Mauery9e801a22018-10-12 13:20:49 -070062std::tuple<std::unique_ptr<Message>, SessionHeader>
63 unflatten(std::vector<uint8_t>& inPacket);
Tom Joseph4e57ada2016-08-10 06:51:12 -050064
Tom Joseph3563f8f2017-05-08 15:42:54 +053065/**
Tom Joseph4e57ada2016-08-10 06:51:12 -050066 * @brief Flatten an IPMI message and generate the IPMI packet with the
67 * session header
68 *
69 * @param[in] outMessage - IPMI message to be flattened
70 * @param[in] authType - Session header type to be added to the IPMI
71 * packet
72 *
73 * @return IPMI packet on success
74 */
Vernon Mauery9e801a22018-10-12 13:20:49 -070075std::vector<uint8_t> flatten(Message& outMessage, SessionHeader authType,
Tom Joseph4e57ada2016-08-10 06:51:12 -050076 session::Session& session);
77
78} // namespace parser
79
80namespace ipmi15parser
81{
82
83struct SessionHeader_t
84{
85 struct parser::BasicHeader_t base;
86 uint32_t sessSeqNum;
87 uint32_t sessId;
88 // <Optional Field: AuthCode>
89 uint8_t payloadLength;
90} __attribute__((packed));
91
92struct SessionTrailer_t
93{
94 uint8_t legacyPad;
95} __attribute__((packed));
96
Tom Joseph3563f8f2017-05-08 15:42:54 +053097/**
Tom Joseph4e57ada2016-08-10 06:51:12 -050098 * @brief Unflatten an incoming packet and prepare the IPMI message
99 *
100 * @param[in] inPacket - Incoming IPMI packet
101 *
102 * @return IPMI message in the packet on success
103 */
104std::unique_ptr<Message> unflatten(std::vector<uint8_t>& inPacket);
105
Tom Joseph3563f8f2017-05-08 15:42:54 +0530106/**
Tom Joseph4e57ada2016-08-10 06:51:12 -0500107 * @brief Flatten an IPMI message and generate the IPMI packet with the
108 * session header
109 *
110 * @param[in] outMessage - IPMI message to be flattened
111 *
112 * @return IPMI packet on success
113 */
114std::vector<uint8_t> flatten(Message& outMessage, session::Session& session);
115
116} // namespace ipmi15parser
117
118namespace ipmi20parser
119{
120
121constexpr size_t MAX_INTEGRITY_DATA_LENGTH = 12;
122constexpr size_t PAYLOAD_ENCRYPT_MASK = 0x80;
123constexpr size_t PAYLOAD_AUTH_MASK = 0x40;
124
125struct SessionHeader_t
126{
127 struct parser::BasicHeader_t base;
128
129 uint8_t payloadType;
130
131 uint32_t sessId;
132 uint32_t sessSeqNum;
133 uint16_t payloadLength;
134} __attribute__((packed));
135
136struct SessionTrailer_t
137{
138 // Integrity Pad
139 uint8_t padLength;
140 uint8_t nextHeader;
Tom Joseph4e57ada2016-08-10 06:51:12 -0500141} __attribute__((packed));
142
Tom Joseph3563f8f2017-05-08 15:42:54 +0530143/**
Tom Joseph4e57ada2016-08-10 06:51:12 -0500144 * @brief Unflatten an incoming packet and prepare the IPMI message
145 *
146 * @param[in] inPacket - Incoming IPMI packet
147 *
148 * @return IPMI message in the packet on success
149 */
150std::unique_ptr<Message> unflatten(std::vector<uint8_t>& inPacket);
151
Tom Joseph3563f8f2017-05-08 15:42:54 +0530152/**
Tom Joseph4e57ada2016-08-10 06:51:12 -0500153 * @brief Flatten an IPMI message and generate the IPMI packet with the
154 * session header
155 *
156 * @param[in] outMessage - IPMI message to be flattened
157 *
158 * @return IPMI packet on success
159 */
160std::vector<uint8_t> flatten(Message& outMessage, session::Session& session);
161
162namespace internal
163{
164
Tom Joseph3563f8f2017-05-08 15:42:54 +0530165/**
Tom Joseph4e57ada2016-08-10 06:51:12 -0500166 * @brief Add sequence number to the message
167 *
168 * @param[in] packet - outgoing packet to which to add sequence number
169 * @param[in] session - session handle
170 *
171 */
172void addSequenceNumber(std::vector<uint8_t>& packet, session::Session& session);
173
Tom Joseph3563f8f2017-05-08 15:42:54 +0530174/**
Tom Joseph64703f42017-01-10 17:03:48 +0530175 * @brief Verify the integrity data of the incoming IPMI packet
176 *
177 * @param[in] packet - Incoming IPMI packet
Tom Joseph027dfc22017-01-26 13:30:53 +0530178 * @param[in] message - IPMI Message populated from the incoming packet
179 * @param[in] payloadLen - Length of the IPMI payload
Tom Joseph64703f42017-01-10 17:03:48 +0530180 *
181 */
182bool verifyPacketIntegrity(const std::vector<uint8_t>& packet,
Vernon Mauery9e801a22018-10-12 13:20:49 -0700183 const Message& message, size_t payloadLen);
Tom Joseph64703f42017-01-10 17:03:48 +0530184
Tom Joseph3563f8f2017-05-08 15:42:54 +0530185/**
Tom Joseph64703f42017-01-10 17:03:48 +0530186 * @brief Add Integrity data to the outgoing IPMI packet
187 *
188 * @param[in] packet - Outgoing IPMI packet
Tom Joseph1404bca2017-01-26 14:17:02 +0530189 * @param[in] message - IPMI Message populated for the outgoing packet
190 * @param[in] payloadLen - Length of the IPMI payload
Tom Joseph64703f42017-01-10 17:03:48 +0530191 */
Vernon Mauery9e801a22018-10-12 13:20:49 -0700192void addIntegrityData(std::vector<uint8_t>& packet, const Message& message,
Tom Joseph1404bca2017-01-26 14:17:02 +0530193 size_t payloadLen);
Tom Joseph64703f42017-01-10 17:03:48 +0530194
Tom Joseph3563f8f2017-05-08 15:42:54 +0530195/**
Tom Joseph78478a82017-01-26 14:24:29 +0530196 * @brief Decrypt the encrypted payload in the incoming IPMI packet
197 *
198 * @param[in] packet - Incoming IPMI packet
199 * @param[in] message - IPMI Message populated from the incoming packet
200 * @param[in] payloadLen - Length of encrypted IPMI payload
201 *
202 * @return on successful completion, return the plain text payload
203 */
204std::vector<uint8_t> decryptPayload(const std::vector<uint8_t>& packet,
Vernon Mauery9e801a22018-10-12 13:20:49 -0700205 const Message& message, size_t payloadLen);
Tom Joseph78478a82017-01-26 14:24:29 +0530206
Tom Joseph3563f8f2017-05-08 15:42:54 +0530207/**
Tom Joseph75362832017-01-26 15:17:04 +0530208 * @brief Encrypt the plain text payload for the outgoing IPMI packet
209 *
210 * @param[in] message - IPMI Message populated for the outgoing packet
211 *
212 * @return on successful completion, return the encrypted payload
213 */
214std::vector<uint8_t> encryptPayload(Message& message);
215
Tom Joseph4e57ada2016-08-10 06:51:12 -0500216} // namespace internal
217
218} // namespace ipmi20parser
219
220} // namespace message