12c95dd1aSWilly Tu #include "config.h"
22c95dd1aSWilly Tu 
38bb10b79STom Joseph #include "rakp12.hpp"
48bb10b79STom Joseph 
59e801a2bSVernon Mauery #include "comm_module.hpp"
69e801a2bSVernon Mauery #include "endian.hpp"
79e801a2bSVernon Mauery #include "guid.hpp"
82085ae07SVernon Mauery #include "sessions_manager.hpp"
99e801a2bSVernon Mauery 
108bb10b79STom Joseph #include <openssl/rand.h>
118bb10b79STom Joseph 
12bc8958feSGeorge Liu #include <ipmid/types.hpp>
137b7f25f7SGeorge Liu #include <phosphor-logging/lg2.hpp>
14bc8958feSGeorge Liu 
158bb10b79STom Joseph #include <algorithm>
1656527b93STom Joseph #include <cstring>
178bb10b79STom Joseph #include <iomanip>
188bb10b79STom Joseph 
198bb10b79STom Joseph namespace command
208bb10b79STom Joseph {
218bb10b79STom Joseph 
isChannelAccessModeEnabled(const uint8_t accessMode)22ecb32fbcSAppaRao Puli bool isChannelAccessModeEnabled(const uint8_t accessMode)
23ecb32fbcSAppaRao Puli {
24ecb32fbcSAppaRao Puli     return accessMode !=
25ecb32fbcSAppaRao Puli            static_cast<uint8_t>(ipmi::EChannelAccessMode::disabled);
26ecb32fbcSAppaRao Puli }
27ecb32fbcSAppaRao Puli 
logInvalidLoginRedfishEvent(const std::string & journalMsg,const std::optional<std::string> & messageArgs)280e0546f1Ssunitakx void logInvalidLoginRedfishEvent(const std::string& journalMsg,
290e0546f1Ssunitakx                                  const std::optional<std::string>& messageArgs)
300e0546f1Ssunitakx {
310e0546f1Ssunitakx     static constexpr std::string_view openBMCMessageRegistryVersion = "0.1.";
320e0546f1Ssunitakx     std::string messageID = "OpenBMC." +
330e0546f1Ssunitakx                             std::string(openBMCMessageRegistryVersion) +
340e0546f1Ssunitakx                             "InvalidLoginAttempted";
357b7f25f7SGeorge Liu     lg2::error(
367b7f25f7SGeorge Liu         "message: {MSG}, id: {REDFISH_MESSAGE_ID}, args: {REDFISH_MESSAGE_ARGS}",
377b7f25f7SGeorge Liu         "MSG", journalMsg, "REDFISH_MESSAGE_ID", messageID,
387b7f25f7SGeorge Liu         "REDFISH_MESSAGE_ARGS", messageArgs.value());
390e0546f1Ssunitakx }
RAKP12(const std::vector<uint8_t> & inPayload,std::shared_ptr<message::Handler> &)4018a45e9dSTom Joseph std::vector<uint8_t> RAKP12(const std::vector<uint8_t>& inPayload,
41be1470ccSGeorge Liu                             std::shared_ptr<message::Handler>& /* handler */)
428bb10b79STom Joseph {
4318a45e9dSTom Joseph     auto request = reinterpret_cast<const RAKP1request*>(inPayload.data());
442b1edef0SZhikui Ren     // verify inPayload minimum size
452b1edef0SZhikui Ren     if (inPayload.size() < (sizeof(*request) - userNameMaxLen))
462b1edef0SZhikui Ren     {
472b1edef0SZhikui Ren         std::vector<uint8_t> errorPayload{IPMI_CC_REQ_DATA_LEN_INVALID};
482b1edef0SZhikui Ren         return errorPayload;
492b1edef0SZhikui Ren     }
502b1edef0SZhikui Ren 
512b1edef0SZhikui Ren     std::vector<uint8_t> outPayload(sizeof(RAKP2response));
528bb10b79STom Joseph     auto response = reinterpret_cast<RAKP2response*>(outPayload.data());
538bb10b79STom Joseph 
548bb10b79STom Joseph     // Session ID zero is reserved for Session Setup
558bb10b79STom Joseph     if (endian::from_ipmi(request->managedSystemSessionID) ==
56f8a34fc4SSuryakanth Sekar         session::sessionZero)
578bb10b79STom Joseph     {
587b7f25f7SGeorge Liu         lg2::info("RAKP12: BMC invalid Session ID");
598bb10b79STom Joseph         response->rmcpStatusCode =
608bb10b79STom Joseph             static_cast<uint8_t>(RAKP_ReturnCode::INVALID_SESSION_ID);
618bb10b79STom Joseph         return outPayload;
628bb10b79STom Joseph     }
638bb10b79STom Joseph 
648bb10b79STom Joseph     std::shared_ptr<session::Session> session;
658bb10b79STom Joseph     try
668bb10b79STom Joseph     {
672085ae07SVernon Mauery         session = session::Manager::get().getSession(
682085ae07SVernon Mauery             endian::from_ipmi(request->managedSystemSessionID));
698bb10b79STom Joseph     }
7012d199b2SPatrick Williams     catch (const std::exception& e)
718bb10b79STom Joseph     {
727b7f25f7SGeorge Liu         lg2::error("RAKP12 : session not found: {ERROR}", "ERROR", e);
738bb10b79STom Joseph         response->rmcpStatusCode =
748bb10b79STom Joseph             static_cast<uint8_t>(RAKP_ReturnCode::INVALID_SESSION_ID);
758bb10b79STom Joseph         return outPayload;
768bb10b79STom Joseph     }
778bb10b79STom Joseph 
78099fb097SPatrick Williams     auto rakp1Size = sizeof(RAKP1request) -
79099fb097SPatrick Williams                      (userNameMaxLen - request->user_name_len);
8056527b93STom Joseph 
810e0546f1Ssunitakx     std::string message = "Invalid login attempted via RCMPP interface ";
8256527b93STom Joseph     // Validate user name length in the message
8356527b93STom Joseph     if (request->user_name_len > userNameMaxLen ||
8456527b93STom Joseph         inPayload.size() != rakp1Size)
8556527b93STom Joseph     {
8656527b93STom Joseph         response->rmcpStatusCode =
8756527b93STom Joseph             static_cast<uint8_t>(RAKP_ReturnCode::INVALID_NAME_LENGTH);
880e0546f1Ssunitakx         logInvalidLoginRedfishEvent(message);
8956527b93STom Joseph         return outPayload;
9056527b93STom Joseph     }
9156527b93STom Joseph 
9256527b93STom Joseph     session->userName.assign(request->user_name, request->user_name_len);
9356527b93STom Joseph 
948bb10b79STom Joseph     // Update transaction time
958bb10b79STom Joseph     session->updateLastTransactionTime();
968bb10b79STom Joseph 
978bb10b79STom Joseph     auto rcSessionID = endian::to_ipmi(session->getRCSessionID());
988bb10b79STom Joseph     auto bmcSessionID = endian::to_ipmi(session->getBMCSessionID());
998bb10b79STom Joseph     auto authAlgo = session->getAuthAlgo();
1008bb10b79STom Joseph 
1018bb10b79STom Joseph     /*
1028bb10b79STom Joseph      * Generate Key Authentication Code - RAKP 2
1038bb10b79STom Joseph      *
1048bb10b79STom Joseph      * 1) Remote Console Session ID - 4 bytes
1058bb10b79STom Joseph      * 2) Managed System Session ID - 4 bytes
1068bb10b79STom Joseph      * 3) Remote Console Random Number - 16 bytes
1078bb10b79STom Joseph      * 4) Managed System Random Number - 16 bytes
1088bb10b79STom Joseph      * 5) Managed System GUID - 16 bytes
1098bb10b79STom Joseph      * 6) Requested Privilege Level - 1 byte
1108bb10b79STom Joseph      * 7) User Name Length Byte - 1 byte (0 for 'null' username)
1118bb10b79STom Joseph      * 8) User Name - variable (absent for 'null' username)
1128bb10b79STom Joseph      */
1138bb10b79STom Joseph 
1148bb10b79STom Joseph     std::vector<uint8_t> input;
1158bb10b79STom Joseph     input.resize(sizeof(rcSessionID) + sizeof(bmcSessionID) +
1168bb10b79STom Joseph                  cipher::rakp_auth::REMOTE_CONSOLE_RANDOM_NUMBER_LEN +
1179e801a2bSVernon Mauery                  cipher::rakp_auth::BMC_RANDOM_NUMBER_LEN + BMC_GUID_LEN +
1189e801a2bSVernon Mauery                  sizeof(request->req_max_privilege_level) +
1199e801a2bSVernon Mauery                  sizeof(request->user_name_len) + session->userName.size());
1208bb10b79STom Joseph 
1218bb10b79STom Joseph     auto iter = input.begin();
1228bb10b79STom Joseph 
1238bb10b79STom Joseph     // Remote Console Session ID
1249e801a2bSVernon Mauery     std::copy_n(reinterpret_cast<uint8_t*>(&rcSessionID), sizeof(rcSessionID),
1259e801a2bSVernon Mauery                 iter);
1268bb10b79STom Joseph     std::advance(iter, sizeof(rcSessionID));
1278bb10b79STom Joseph 
1288bb10b79STom Joseph     // Managed System Session ID
1298bb10b79STom Joseph     std::copy_n(reinterpret_cast<uint8_t*>(&bmcSessionID), sizeof(bmcSessionID),
1308bb10b79STom Joseph                 iter);
1318bb10b79STom Joseph     std::advance(iter, sizeof(bmcSessionID));
1328bb10b79STom Joseph 
1338bb10b79STom Joseph     // Copy the Remote Console Random Number from the RAKP1 request to the
1348bb10b79STom Joseph     // Authentication Algorithm
1359e801a2bSVernon Mauery     std::copy_n(
1369e801a2bSVernon Mauery         reinterpret_cast<const uint8_t*>(request->remote_console_random_number),
1378bb10b79STom Joseph         cipher::rakp_auth::REMOTE_CONSOLE_RANDOM_NUMBER_LEN,
1388bb10b79STom Joseph         authAlgo->rcRandomNum.begin());
1398bb10b79STom Joseph 
1409e801a2bSVernon Mauery     std::copy(authAlgo->rcRandomNum.begin(), authAlgo->rcRandomNum.end(), iter);
1418bb10b79STom Joseph     std::advance(iter, cipher::rakp_auth::REMOTE_CONSOLE_RANDOM_NUMBER_LEN);
1428bb10b79STom Joseph 
1438bb10b79STom Joseph     // Generate the Managed System Random Number
1448bb10b79STom Joseph     if (!RAND_bytes(input.data() + sizeof(rcSessionID) + sizeof(bmcSessionID) +
1458bb10b79STom Joseph                         cipher::rakp_auth::REMOTE_CONSOLE_RANDOM_NUMBER_LEN,
1468bb10b79STom Joseph                     cipher::rakp_auth::BMC_RANDOM_NUMBER_LEN))
1478bb10b79STom Joseph     {
1488bb10b79STom Joseph         response->rmcpStatusCode =
1498bb10b79STom Joseph             static_cast<uint8_t>(RAKP_ReturnCode::INSUFFICIENT_RESOURCE);
1508bb10b79STom Joseph         return outPayload;
1518bb10b79STom Joseph     }
152d5a4f45eSRichard Marian Thomaiyar     // As stated in Set Session Privilege Level command in IPMI Spec, when
1532555e2ecSjayaprakash Mutyala     // creating a session through Activate command / RAKP 1 message, it must
1542555e2ecSjayaprakash Mutyala     // be established with USER privilege as well as all other sessions are
1552555e2ecSjayaprakash Mutyala     // initially set to USER privilege, regardless of the requested maximum
1562555e2ecSjayaprakash Mutyala     // privilege.
1572555e2ecSjayaprakash Mutyala     if (!(static_cast<session::Privilege>(request->req_max_privilege_level &
158d5a4f45eSRichard Marian Thomaiyar                                           session::reqMaxPrivMask) >
1592555e2ecSjayaprakash Mutyala           session::Privilege::CALLBACK))
160d5a4f45eSRichard Marian Thomaiyar     {
1612555e2ecSjayaprakash Mutyala         response->rmcpStatusCode =
1622555e2ecSjayaprakash Mutyala             static_cast<uint8_t>(RAKP_ReturnCode::UNAUTH_ROLE_PRIV);
1632555e2ecSjayaprakash Mutyala         return outPayload;
164d5a4f45eSRichard Marian Thomaiyar     }
1652555e2ecSjayaprakash Mutyala     session->currentPrivilege(static_cast<uint8_t>(session::Privilege::USER));
1662555e2ecSjayaprakash Mutyala 
1674021b1f7STom Joseph     session->reqMaxPrivLevel =
1684021b1f7STom Joseph         static_cast<session::Privilege>(request->req_max_privilege_level);
169d91fd9d2SRichard Marian Thomaiyar     if (request->user_name_len == 0)
170127748a8SRichard Marian Thomaiyar     {
171d91fd9d2SRichard Marian Thomaiyar         // Bail out, if user name is not specified.
172d91fd9d2SRichard Marian Thomaiyar         // Yes, NULL user name is not supported for security reasons.
173127748a8SRichard Marian Thomaiyar         response->rmcpStatusCode =
174127748a8SRichard Marian Thomaiyar             static_cast<uint8_t>(RAKP_ReturnCode::UNAUTH_NAME);
1750e0546f1Ssunitakx         logInvalidLoginRedfishEvent(message);
176127748a8SRichard Marian Thomaiyar         return outPayload;
177127748a8SRichard Marian Thomaiyar     }
178127748a8SRichard Marian Thomaiyar 
179127748a8SRichard Marian Thomaiyar     // Perform user name based lookup
180127748a8SRichard Marian Thomaiyar     std::string userName(request->user_name, request->user_name_len);
18105c1447dSJayaprakash Mutyala     ipmi::SecureString passwd;
182127748a8SRichard Marian Thomaiyar     uint8_t userId = ipmi::ipmiUserGetUserId(userName);
183127748a8SRichard Marian Thomaiyar     if (userId == ipmi::invalidUserId)
184127748a8SRichard Marian Thomaiyar     {
185127748a8SRichard Marian Thomaiyar         response->rmcpStatusCode =
186127748a8SRichard Marian Thomaiyar             static_cast<uint8_t>(RAKP_ReturnCode::UNAUTH_NAME);
1870e0546f1Ssunitakx         logInvalidLoginRedfishEvent(message);
188127748a8SRichard Marian Thomaiyar         return outPayload;
189127748a8SRichard Marian Thomaiyar     }
190127748a8SRichard Marian Thomaiyar     // check user is enabled before proceeding.
191127748a8SRichard Marian Thomaiyar     bool userEnabled = false;
192127748a8SRichard Marian Thomaiyar     ipmi::ipmiUserCheckEnabled(userId, userEnabled);
193127748a8SRichard Marian Thomaiyar     if (!userEnabled)
194127748a8SRichard Marian Thomaiyar     {
195127748a8SRichard Marian Thomaiyar         response->rmcpStatusCode =
196127748a8SRichard Marian Thomaiyar             static_cast<uint8_t>(RAKP_ReturnCode::INACTIVE_ROLE);
1970e0546f1Ssunitakx         logInvalidLoginRedfishEvent(message);
198127748a8SRichard Marian Thomaiyar         return outPayload;
199127748a8SRichard Marian Thomaiyar     }
2004c4694efSRichard Marian Thomaiyar     // Get the user password for RAKP message authenticate
2014c4694efSRichard Marian Thomaiyar     passwd = ipmi::ipmiUserGetPassword(userName);
2024c4694efSRichard Marian Thomaiyar     if (passwd.empty())
2034c4694efSRichard Marian Thomaiyar     {
2044c4694efSRichard Marian Thomaiyar         response->rmcpStatusCode =
2054c4694efSRichard Marian Thomaiyar             static_cast<uint8_t>(RAKP_ReturnCode::UNAUTH_NAME);
2060e0546f1Ssunitakx         logInvalidLoginRedfishEvent(message);
2074c4694efSRichard Marian Thomaiyar         return outPayload;
2084c4694efSRichard Marian Thomaiyar     }
2092c95dd1aSWilly Tu #ifdef PAM_AUTHENTICATE
210b31e9695SAyushi Smriti     // Check whether user is already locked for failed attempts
211b31e9695SAyushi Smriti     if (!ipmi::ipmiUserPamAuthenticate(userName, passwd))
212b31e9695SAyushi Smriti     {
2137b7f25f7SGeorge Liu         lg2::error(
2147b7f25f7SGeorge Liu             "Authentication failed - user already locked out, user id: {ID}",
2157b7f25f7SGeorge Liu             "ID", userId);
216b31e9695SAyushi Smriti 
217b31e9695SAyushi Smriti         response->rmcpStatusCode =
218b31e9695SAyushi Smriti             static_cast<uint8_t>(RAKP_ReturnCode::UNAUTH_NAME);
2190e0546f1Ssunitakx         logInvalidLoginRedfishEvent(message);
220b31e9695SAyushi Smriti         return outPayload;
221b31e9695SAyushi Smriti     }
2222c95dd1aSWilly Tu #endif
223d9c86bb7SSaravanan Palanisamy 
224d9c86bb7SSaravanan Palanisamy     uint8_t chNum = static_cast<uint8_t>(getInterfaceIndex());
225127748a8SRichard Marian Thomaiyar     // Get channel based access information
226992e53c7SRichard Marian Thomaiyar     if ((ipmi::ipmiUserGetPrivilegeAccess(
227992e53c7SRichard Marian Thomaiyar              userId, chNum, session->sessionUserPrivAccess) != IPMI_CC_OK) ||
228992e53c7SRichard Marian Thomaiyar         (ipmi::getChannelAccessData(chNum, session->sessionChannelAccess) !=
229992e53c7SRichard Marian Thomaiyar          IPMI_CC_OK))
230127748a8SRichard Marian Thomaiyar     {
231127748a8SRichard Marian Thomaiyar         response->rmcpStatusCode =
232127748a8SRichard Marian Thomaiyar             static_cast<uint8_t>(RAKP_ReturnCode::INACTIVE_ROLE);
2330e0546f1Ssunitakx         logInvalidLoginRedfishEvent(message);
234127748a8SRichard Marian Thomaiyar         return outPayload;
235127748a8SRichard Marian Thomaiyar     }
236ecb32fbcSAppaRao Puli     if (!isChannelAccessModeEnabled(session->sessionChannelAccess.accessMode))
237ecb32fbcSAppaRao Puli     {
2387b7f25f7SGeorge Liu         lg2::error("Channel access mode disabled.");
239ecb32fbcSAppaRao Puli         response->rmcpStatusCode =
240ecb32fbcSAppaRao Puli             static_cast<uint8_t>(RAKP_ReturnCode::INACTIVE_ROLE);
2410e0546f1Ssunitakx         logInvalidLoginRedfishEvent(message);
242ecb32fbcSAppaRao Puli         return outPayload;
243ecb32fbcSAppaRao Puli     }
244992e53c7SRichard Marian Thomaiyar     if (session->sessionUserPrivAccess.privilege >
245992e53c7SRichard Marian Thomaiyar         static_cast<uint8_t>(session::Privilege::OEM))
2467e5d38d2SRichard Marian Thomaiyar     {
2477e5d38d2SRichard Marian Thomaiyar         response->rmcpStatusCode =
2487e5d38d2SRichard Marian Thomaiyar             static_cast<uint8_t>(RAKP_ReturnCode::INACTIVE_ROLE);
2490e0546f1Ssunitakx         logInvalidLoginRedfishEvent(message);
2507e5d38d2SRichard Marian Thomaiyar         return outPayload;
2517e5d38d2SRichard Marian Thomaiyar     }
252f8a34fc4SSuryakanth Sekar     session->channelNum(chNum);
253f8a34fc4SSuryakanth Sekar     session->userID(userId);
2542555e2ecSjayaprakash Mutyala     // minimum privilege of Channel / User / session::privilege::USER
255d5a4f45eSRichard Marian Thomaiyar     // has to be used as session current privilege level
256127748a8SRichard Marian Thomaiyar     uint8_t minPriv = 0;
257992e53c7SRichard Marian Thomaiyar     if (session->sessionChannelAccess.privLimit <
258992e53c7SRichard Marian Thomaiyar         session->sessionUserPrivAccess.privilege)
259127748a8SRichard Marian Thomaiyar     {
260992e53c7SRichard Marian Thomaiyar         minPriv = session->sessionChannelAccess.privLimit;
261127748a8SRichard Marian Thomaiyar     }
262127748a8SRichard Marian Thomaiyar     else
263127748a8SRichard Marian Thomaiyar     {
264992e53c7SRichard Marian Thomaiyar         minPriv = session->sessionUserPrivAccess.privilege;
265127748a8SRichard Marian Thomaiyar     }
266f8a34fc4SSuryakanth Sekar     if (session->currentPrivilege() > minPriv)
267127748a8SRichard Marian Thomaiyar     {
268f8a34fc4SSuryakanth Sekar         session->currentPrivilege(static_cast<uint8_t>(minPriv));
269127748a8SRichard Marian Thomaiyar     }
270d91fd9d2SRichard Marian Thomaiyar     // For username / privilege lookup, fail with UNAUTH_NAME, if requested
271d8e92fe1SRichard Marian Thomaiyar     // max privilege does not match user privilege
272d91fd9d2SRichard Marian Thomaiyar     if (((request->req_max_privilege_level & userNameOnlyLookupMask) ==
273d91fd9d2SRichard Marian Thomaiyar          userNamePrivLookup) &&
274d8e92fe1SRichard Marian Thomaiyar         ((request->req_max_privilege_level & session::reqMaxPrivMask) !=
275992e53c7SRichard Marian Thomaiyar          session->sessionUserPrivAccess.privilege))
276d91fd9d2SRichard Marian Thomaiyar     {
2777b7f25f7SGeorge Liu         lg2::info("Username/Privilege lookup failed for requested privilege");
278d91fd9d2SRichard Marian Thomaiyar         response->rmcpStatusCode =
279d91fd9d2SRichard Marian Thomaiyar             static_cast<uint8_t>(RAKP_ReturnCode::UNAUTH_NAME);
2800e0546f1Ssunitakx 
2810e0546f1Ssunitakx         logInvalidLoginRedfishEvent(message);
282d91fd9d2SRichard Marian Thomaiyar         return outPayload;
283d91fd9d2SRichard Marian Thomaiyar     }
284127748a8SRichard Marian Thomaiyar 
285127748a8SRichard Marian Thomaiyar     std::fill(authAlgo->userKey.data(),
286127748a8SRichard Marian Thomaiyar               authAlgo->userKey.data() + authAlgo->userKey.size(), 0);
287127748a8SRichard Marian Thomaiyar     std::copy_n(passwd.c_str(), passwd.size(), authAlgo->userKey.data());
28899b87849SRichard Marian Thomaiyar 
2898bb10b79STom Joseph     // Copy the Managed System Random Number to the Authentication Algorithm
2908bb10b79STom Joseph     std::copy_n(iter, cipher::rakp_auth::BMC_RANDOM_NUMBER_LEN,
2918bb10b79STom Joseph                 authAlgo->bmcRandomNum.begin());
2928bb10b79STom Joseph     std::advance(iter, cipher::rakp_auth::BMC_RANDOM_NUMBER_LEN);
2938bb10b79STom Joseph 
2948bb10b79STom Joseph     // Managed System GUID
295*36e3c539SVernon Mauery     const Guid& guid = command::getSystemGUID();
296*36e3c539SVernon Mauery     std::copy_n(guid.data(), guid.size(), iter);
2978bb10b79STom Joseph     std::advance(iter, BMC_GUID_LEN);
2988bb10b79STom Joseph 
2998bb10b79STom Joseph     // Requested Privilege Level
3008bb10b79STom Joseph     std::copy_n(&(request->req_max_privilege_level),
3018bb10b79STom Joseph                 sizeof(request->req_max_privilege_level), iter);
3028bb10b79STom Joseph     std::advance(iter, sizeof(request->req_max_privilege_level));
3038bb10b79STom Joseph 
3048bb10b79STom Joseph     // User Name Length Byte
3058bb10b79STom Joseph     std::copy_n(&(request->user_name_len), sizeof(request->user_name_len),
3068bb10b79STom Joseph                 iter);
30756527b93STom Joseph     std::advance(iter, sizeof(request->user_name_len));
30856527b93STom Joseph 
30956527b93STom Joseph     std::copy_n(session->userName.data(), session->userName.size(), iter);
3108bb10b79STom Joseph 
3118bb10b79STom Joseph     // Generate Key Exchange Authentication Code - RAKP2
3128bb10b79STom Joseph     auto output = authAlgo->generateHMAC(input);
3138bb10b79STom Joseph 
3148bb10b79STom Joseph     response->messageTag = request->messageTag;
3158bb10b79STom Joseph     response->rmcpStatusCode = static_cast<uint8_t>(RAKP_ReturnCode::NO_ERROR);
3168bb10b79STom Joseph     response->reserved = 0;
3178bb10b79STom Joseph     response->remoteConsoleSessionID = rcSessionID;
3188bb10b79STom Joseph 
3198bb10b79STom Joseph     // Copy Managed System Random Number to the Response
3208bb10b79STom Joseph     std::copy(authAlgo->bmcRandomNum.begin(), authAlgo->bmcRandomNum.end(),
3218bb10b79STom Joseph               response->managed_system_random_number);
3228bb10b79STom Joseph 
3238bb10b79STom Joseph     // Copy System GUID to the Response
324*36e3c539SVernon Mauery     std::copy_n(guid.data(), guid.size(), response->managed_system_guid);
3258bb10b79STom Joseph 
3268bb10b79STom Joseph     // Insert the HMAC output into the payload
3278bb10b79STom Joseph     outPayload.insert(outPayload.end(), output.begin(), output.end());
3288bb10b79STom Joseph     return outPayload;
3298bb10b79STom Joseph }
3308bb10b79STom Joseph 
3318bb10b79STom Joseph } // namespace command
332