18bb10b79STom Joseph #include "rakp12.hpp"
28bb10b79STom Joseph 
39e801a2bSVernon Mauery #include "comm_module.hpp"
49e801a2bSVernon Mauery #include "endian.hpp"
59e801a2bSVernon Mauery #include "guid.hpp"
62085ae07SVernon Mauery #include "sessions_manager.hpp"
79e801a2bSVernon Mauery 
88bb10b79STom Joseph #include <openssl/rand.h>
98bb10b79STom Joseph 
108bb10b79STom Joseph #include <algorithm>
1156527b93STom Joseph #include <cstring>
128bb10b79STom Joseph #include <iomanip>
13fc37e59eSVernon Mauery #include <phosphor-logging/log.hpp>
148bb10b79STom Joseph 
15fc37e59eSVernon Mauery using namespace phosphor::logging;
16fc37e59eSVernon Mauery 
178bb10b79STom Joseph namespace command
188bb10b79STom Joseph {
198bb10b79STom Joseph 
20ecb32fbcSAppaRao Puli bool isChannelAccessModeEnabled(const uint8_t accessMode)
21ecb32fbcSAppaRao Puli {
22ecb32fbcSAppaRao Puli     return accessMode !=
23ecb32fbcSAppaRao Puli            static_cast<uint8_t>(ipmi::EChannelAccessMode::disabled);
24ecb32fbcSAppaRao Puli }
25ecb32fbcSAppaRao Puli 
26*0e0546f1Ssunitakx void logInvalidLoginRedfishEvent(const std::string& journalMsg,
27*0e0546f1Ssunitakx                                  const std::optional<std::string>& messageArgs)
28*0e0546f1Ssunitakx {
29*0e0546f1Ssunitakx     static constexpr std::string_view openBMCMessageRegistryVersion = "0.1.";
30*0e0546f1Ssunitakx     std::string messageID = "OpenBMC." +
31*0e0546f1Ssunitakx                             std::string(openBMCMessageRegistryVersion) +
32*0e0546f1Ssunitakx                             "InvalidLoginAttempted";
33*0e0546f1Ssunitakx     phosphor::logging::log<phosphor::logging::level::ERR>(
34*0e0546f1Ssunitakx         journalMsg.c_str(),
35*0e0546f1Ssunitakx         phosphor::logging::entry("REDFISH_MESSAGE_ID=%s", messageID.c_str()),
36*0e0546f1Ssunitakx         phosphor::logging::entry("REDFISH_MESSAGE_ARGS=%s",
37*0e0546f1Ssunitakx                                  messageArgs.value().c_str()));
38*0e0546f1Ssunitakx }
3918a45e9dSTom Joseph std::vector<uint8_t> RAKP12(const std::vector<uint8_t>& inPayload,
4041ff9b51SVernon Mauery                             std::shared_ptr<message::Handler>& handler)
418bb10b79STom Joseph {
4218a45e9dSTom Joseph     auto request = reinterpret_cast<const RAKP1request*>(inPayload.data());
432b1edef0SZhikui Ren     // verify inPayload minimum size
442b1edef0SZhikui Ren     if (inPayload.size() < (sizeof(*request) - userNameMaxLen))
452b1edef0SZhikui Ren     {
462b1edef0SZhikui Ren         std::vector<uint8_t> errorPayload{IPMI_CC_REQ_DATA_LEN_INVALID};
472b1edef0SZhikui Ren         return errorPayload;
482b1edef0SZhikui Ren     }
492b1edef0SZhikui Ren 
502b1edef0SZhikui Ren     std::vector<uint8_t> outPayload(sizeof(RAKP2response));
518bb10b79STom Joseph     auto response = reinterpret_cast<RAKP2response*>(outPayload.data());
528bb10b79STom Joseph 
538bb10b79STom Joseph     // Session ID zero is reserved for Session Setup
548bb10b79STom Joseph     if (endian::from_ipmi(request->managedSystemSessionID) ==
55f8a34fc4SSuryakanth Sekar         session::sessionZero)
568bb10b79STom Joseph     {
57fc37e59eSVernon Mauery         log<level::INFO>("RAKP12: BMC invalid Session ID");
588bb10b79STom Joseph         response->rmcpStatusCode =
598bb10b79STom Joseph             static_cast<uint8_t>(RAKP_ReturnCode::INVALID_SESSION_ID);
608bb10b79STom Joseph         return outPayload;
618bb10b79STom Joseph     }
628bb10b79STom Joseph 
638bb10b79STom Joseph     std::shared_ptr<session::Session> session;
648bb10b79STom Joseph     try
658bb10b79STom Joseph     {
662085ae07SVernon Mauery         session = session::Manager::get().getSession(
672085ae07SVernon Mauery             endian::from_ipmi(request->managedSystemSessionID));
688bb10b79STom Joseph     }
698bb10b79STom Joseph     catch (std::exception& e)
708bb10b79STom Joseph     {
71fc37e59eSVernon Mauery         log<level::ERR>("RAKP12 : session not found",
72fc37e59eSVernon Mauery                         entry("EXCEPTION=%s", e.what()));
738bb10b79STom Joseph         response->rmcpStatusCode =
748bb10b79STom Joseph             static_cast<uint8_t>(RAKP_ReturnCode::INVALID_SESSION_ID);
758bb10b79STom Joseph         return outPayload;
768bb10b79STom Joseph     }
778bb10b79STom Joseph 
789e801a2bSVernon Mauery     auto rakp1Size =
799e801a2bSVernon Mauery         sizeof(RAKP1request) - (userNameMaxLen - request->user_name_len);
8056527b93STom Joseph 
81*0e0546f1Ssunitakx     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);
88*0e0546f1Ssunitakx         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);
175*0e0546f1Ssunitakx         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);
181127748a8SRichard Marian Thomaiyar     std::string passwd;
182*0e0546f1Ssunitakx 
183*0e0546f1Ssunitakx     message += "user: " + userName;
184127748a8SRichard Marian Thomaiyar     uint8_t userId = ipmi::ipmiUserGetUserId(userName);
185127748a8SRichard Marian Thomaiyar     if (userId == ipmi::invalidUserId)
186127748a8SRichard Marian Thomaiyar     {
187127748a8SRichard Marian Thomaiyar         response->rmcpStatusCode =
188127748a8SRichard Marian Thomaiyar             static_cast<uint8_t>(RAKP_ReturnCode::UNAUTH_NAME);
189*0e0546f1Ssunitakx         logInvalidLoginRedfishEvent(message);
190127748a8SRichard Marian Thomaiyar         return outPayload;
191127748a8SRichard Marian Thomaiyar     }
192127748a8SRichard Marian Thomaiyar     // check user is enabled before proceeding.
193127748a8SRichard Marian Thomaiyar     bool userEnabled = false;
194127748a8SRichard Marian Thomaiyar     ipmi::ipmiUserCheckEnabled(userId, userEnabled);
195127748a8SRichard Marian Thomaiyar     if (!userEnabled)
196127748a8SRichard Marian Thomaiyar     {
197127748a8SRichard Marian Thomaiyar         response->rmcpStatusCode =
198127748a8SRichard Marian Thomaiyar             static_cast<uint8_t>(RAKP_ReturnCode::INACTIVE_ROLE);
199*0e0546f1Ssunitakx         logInvalidLoginRedfishEvent(message);
200127748a8SRichard Marian Thomaiyar         return outPayload;
201127748a8SRichard Marian Thomaiyar     }
2024c4694efSRichard Marian Thomaiyar     // Get the user password for RAKP message authenticate
2034c4694efSRichard Marian Thomaiyar     passwd = ipmi::ipmiUserGetPassword(userName);
2044c4694efSRichard Marian Thomaiyar     if (passwd.empty())
2054c4694efSRichard Marian Thomaiyar     {
2064c4694efSRichard Marian Thomaiyar         response->rmcpStatusCode =
2074c4694efSRichard Marian Thomaiyar             static_cast<uint8_t>(RAKP_ReturnCode::UNAUTH_NAME);
208*0e0546f1Ssunitakx         logInvalidLoginRedfishEvent(message);
2094c4694efSRichard Marian Thomaiyar         return outPayload;
2104c4694efSRichard Marian Thomaiyar     }
211b31e9695SAyushi Smriti     // Check whether user is already locked for failed attempts
212b31e9695SAyushi Smriti     if (!ipmi::ipmiUserPamAuthenticate(userName, passwd))
213b31e9695SAyushi Smriti     {
214b31e9695SAyushi Smriti         log<level::ERR>("Authentication failed - user already locked out",
215b31e9695SAyushi Smriti                         entry("USER-ID=%d", static_cast<uint8_t>(userId)));
216b31e9695SAyushi Smriti 
217b31e9695SAyushi Smriti         response->rmcpStatusCode =
218b31e9695SAyushi Smriti             static_cast<uint8_t>(RAKP_ReturnCode::UNAUTH_NAME);
219*0e0546f1Ssunitakx         logInvalidLoginRedfishEvent(message);
220b31e9695SAyushi Smriti         return outPayload;
221b31e9695SAyushi Smriti     }
222d9c86bb7SSaravanan Palanisamy 
223d9c86bb7SSaravanan Palanisamy     uint8_t chNum = static_cast<uint8_t>(getInterfaceIndex());
224127748a8SRichard Marian Thomaiyar     // Get channel based access information
225992e53c7SRichard Marian Thomaiyar     if ((ipmi::ipmiUserGetPrivilegeAccess(
226992e53c7SRichard Marian Thomaiyar              userId, chNum, session->sessionUserPrivAccess) != IPMI_CC_OK) ||
227992e53c7SRichard Marian Thomaiyar         (ipmi::getChannelAccessData(chNum, session->sessionChannelAccess) !=
228992e53c7SRichard Marian Thomaiyar          IPMI_CC_OK))
229127748a8SRichard Marian Thomaiyar     {
230127748a8SRichard Marian Thomaiyar         response->rmcpStatusCode =
231127748a8SRichard Marian Thomaiyar             static_cast<uint8_t>(RAKP_ReturnCode::INACTIVE_ROLE);
232*0e0546f1Ssunitakx         logInvalidLoginRedfishEvent(message);
233127748a8SRichard Marian Thomaiyar         return outPayload;
234127748a8SRichard Marian Thomaiyar     }
235ecb32fbcSAppaRao Puli     if (!isChannelAccessModeEnabled(session->sessionChannelAccess.accessMode))
236ecb32fbcSAppaRao Puli     {
237ecb32fbcSAppaRao Puli         phosphor::logging::log<phosphor::logging::level::ERR>(
238ecb32fbcSAppaRao Puli             "Channel access mode disabled.");
239ecb32fbcSAppaRao Puli         response->rmcpStatusCode =
240ecb32fbcSAppaRao Puli             static_cast<uint8_t>(RAKP_ReturnCode::INACTIVE_ROLE);
241*0e0546f1Ssunitakx         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);
249*0e0546f1Ssunitakx         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     {
277fc37e59eSVernon Mauery         log<level::INFO>(
278fc37e59eSVernon Mauery             "Username/Privilege lookup failed for requested privilege");
279d91fd9d2SRichard Marian Thomaiyar         response->rmcpStatusCode =
280d91fd9d2SRichard Marian Thomaiyar             static_cast<uint8_t>(RAKP_ReturnCode::UNAUTH_NAME);
281*0e0546f1Ssunitakx 
282*0e0546f1Ssunitakx         logInvalidLoginRedfishEvent(message);
283d91fd9d2SRichard Marian Thomaiyar         return outPayload;
284d91fd9d2SRichard Marian Thomaiyar     }
285127748a8SRichard Marian Thomaiyar 
286127748a8SRichard Marian Thomaiyar     std::fill(authAlgo->userKey.data(),
287127748a8SRichard Marian Thomaiyar               authAlgo->userKey.data() + authAlgo->userKey.size(), 0);
288127748a8SRichard Marian Thomaiyar     std::copy_n(passwd.c_str(), passwd.size(), authAlgo->userKey.data());
28999b87849SRichard Marian Thomaiyar 
2908bb10b79STom Joseph     // Copy the Managed System Random Number to the Authentication Algorithm
2918bb10b79STom Joseph     std::copy_n(iter, cipher::rakp_auth::BMC_RANDOM_NUMBER_LEN,
2928bb10b79STom Joseph                 authAlgo->bmcRandomNum.begin());
2938bb10b79STom Joseph     std::advance(iter, cipher::rakp_auth::BMC_RANDOM_NUMBER_LEN);
2948bb10b79STom Joseph 
2958bb10b79STom Joseph     // Managed System GUID
29683029cb8STom Joseph     std::copy_n(cache::guid.data(), cache::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
3249e801a2bSVernon Mauery     std::copy_n(cache::guid.data(), cache::guid.size(),
32583029cb8STom Joseph                 response->managed_system_guid);
3268bb10b79STom Joseph 
3278bb10b79STom Joseph     // Insert the HMAC output into the payload
3288bb10b79STom Joseph     outPayload.insert(outPayload.end(), output.begin(), output.end());
3298bb10b79STom Joseph     return outPayload;
3308bb10b79STom Joseph }
3318bb10b79STom Joseph 
3328bb10b79STom Joseph } // namespace command
333