blob: ea737d50347b645ab39817a0f0e369aa3bf11c78 [file] [log] [blame]
Patrick Venture5794fcf2017-10-26 11:11:14 -07001#include "channel.hpp"
Patrick Venture5794fcf2017-10-26 11:11:14 -07002
Johnathan Mantey74a21022018-12-13 13:17:56 -08003#include "user_channel/channel_layer.hpp"
Patrick Venture0b02be92018-08-31 11:55:55 -07004
Patrick Venture5794fcf2017-10-26 11:11:14 -07005#include <arpa/inet.h>
6
Vernon Mauery33250242019-03-12 16:49:26 -07007#include <ipmid/types.hpp>
Vernon Mauery6a98fe72019-03-11 15:57:48 -07008#include <ipmid/utils.hpp>
Patrick Venture5794fcf2017-10-26 11:11:14 -07009#include <phosphor-logging/elog-errors.hpp>
George Liu05e93872024-07-17 14:48:14 +080010#include <phosphor-logging/lg2.hpp>
Patrick Williamsfbc6c9d2023-05-10 07:50:16 -050011#include <xyz/openbmc_project/Common/error.hpp>
12
13#include <fstream>
Richard Marian Thomaiyarf301f042019-01-16 15:56:16 +053014#include <set>
Patrick Venture0b02be92018-08-31 11:55:55 -070015#include <string>
Patrick Venture5794fcf2017-10-26 11:11:14 -070016
17using namespace phosphor::logging;
Willy Tu523e2d12023-09-05 11:36:48 -070018using namespace sdbusplus::error::xyz::openbmc_project::common;
Patrick Venture5794fcf2017-10-26 11:11:14 -070019
George Liucc96b422025-07-08 14:18:48 +080020namespace ipmi
21{
22constexpr Cc ccPayloadTypeNotSupported = 0x80;
23
24static inline auto responsePayloadTypeNotSupported()
25{
26 return response(ccPayloadTypeNotSupported);
27}
28} // namespace ipmi
29
Tom Joseph7cbe2282018-03-21 21:17:33 +053030namespace cipher
31{
32
33/** @brief Get the supported Cipher records
34 *
Richard Marian Thomaiyarf301f042019-01-16 15:56:16 +053035 * The cipher records are read from the JSON file and converted into
36 * 1. cipher suite record format mentioned in the IPMI specification. The
37 * records can be either OEM or standard cipher. Each json entry is parsed and
38 * converted into the cipher record format and pushed into the vector.
39 * 2. Algorithms listed in vector format
Tom Joseph7cbe2282018-03-21 21:17:33 +053040 *
Richard Marian Thomaiyarf301f042019-01-16 15:56:16 +053041 * @return pair of vector containing 1. all the cipher suite records. 2.
42 * Algorithms supported
Tom Joseph7cbe2282018-03-21 21:17:33 +053043 *
44 */
Richard Marian Thomaiyarf301f042019-01-16 15:56:16 +053045std::pair<std::vector<uint8_t>, std::vector<uint8_t>> getCipherRecords()
Tom Joseph7cbe2282018-03-21 21:17:33 +053046{
Richard Marian Thomaiyarf301f042019-01-16 15:56:16 +053047 std::vector<uint8_t> cipherRecords;
48 std::vector<uint8_t> supportedAlgorithmRecords;
49 // create set to get the unique supported algorithms
50 std::set<uint8_t> supportedAlgorithmSet;
Tom Joseph7cbe2282018-03-21 21:17:33 +053051
52 std::ifstream jsonFile(configFile);
53 if (!jsonFile.is_open())
54 {
George Liu05e93872024-07-17 14:48:14 +080055 lg2::error("Channel Cipher suites file not found");
Tom Joseph7cbe2282018-03-21 21:17:33 +053056 elog<InternalFailure>();
57 }
58
59 auto data = Json::parse(jsonFile, nullptr, false);
60 if (data.is_discarded())
61 {
George Liu05e93872024-07-17 14:48:14 +080062 lg2::error("Parsing channel cipher suites JSON failed");
Tom Joseph7cbe2282018-03-21 21:17:33 +053063 elog<InternalFailure>();
64 }
65
66 for (const auto& record : data)
67 {
68 if (record.find(oem) != record.end())
69 {
70 // OEM cipher suite - 0xC1
Richard Marian Thomaiyarf301f042019-01-16 15:56:16 +053071 cipherRecords.push_back(oemCipherSuite);
Tom Joseph7cbe2282018-03-21 21:17:33 +053072 // Cipher Suite ID
Richard Marian Thomaiyarf301f042019-01-16 15:56:16 +053073 cipherRecords.push_back(record.value(cipher, 0));
Tom Joseph7cbe2282018-03-21 21:17:33 +053074 // OEM IANA - 3 bytes
Richard Marian Thomaiyarf301f042019-01-16 15:56:16 +053075 cipherRecords.push_back(record.value(oem, 0));
76 cipherRecords.push_back(record.value(oem, 0) >> 8);
77 cipherRecords.push_back(record.value(oem, 0) >> 16);
Tom Joseph7cbe2282018-03-21 21:17:33 +053078 }
79 else
80 {
Richard Marian Thomaiyarf301f042019-01-16 15:56:16 +053081 // Standard cipher suite - 0xC0
82 cipherRecords.push_back(stdCipherSuite);
Tom Joseph7cbe2282018-03-21 21:17:33 +053083 // Cipher Suite ID
Richard Marian Thomaiyarf301f042019-01-16 15:56:16 +053084 cipherRecords.push_back(record.value(cipher, 0));
Tom Joseph7cbe2282018-03-21 21:17:33 +053085 }
86
87 // Authentication algorithm number
Richard Marian Thomaiyarf301f042019-01-16 15:56:16 +053088 cipherRecords.push_back(record.value(auth, 0));
89 supportedAlgorithmSet.insert(record.value(auth, 0));
90
Tom Joseph7cbe2282018-03-21 21:17:33 +053091 // Integrity algorithm number
Richard Marian Thomaiyarf301f042019-01-16 15:56:16 +053092 cipherRecords.push_back(record.value(integrity, 0) | integrityTag);
93 supportedAlgorithmSet.insert(record.value(integrity, 0) | integrityTag);
94
Tom Joseph7cbe2282018-03-21 21:17:33 +053095 // Confidentiality algorithm number
Richard Marian Thomaiyarf301f042019-01-16 15:56:16 +053096 cipherRecords.push_back(record.value(conf, 0) | confTag);
97 supportedAlgorithmSet.insert(record.value(conf, 0) | confTag);
Tom Joseph7cbe2282018-03-21 21:17:33 +053098 }
99
Richard Marian Thomaiyarf301f042019-01-16 15:56:16 +0530100 // copy the set to supportedAlgorithmRecord which is vector based.
101 std::copy(supportedAlgorithmSet.begin(), supportedAlgorithmSet.end(),
102 std::back_inserter(supportedAlgorithmRecords));
103
104 return std::make_pair(cipherRecords, supportedAlgorithmRecords);
Tom Joseph7cbe2282018-03-21 21:17:33 +0530105}
106
Patrick Venture0b02be92018-08-31 11:55:55 -0700107} // namespace cipher
Tom Joseph7cbe2282018-03-21 21:17:33 +0530108
Ayushi Smriti5c3b72c2019-08-30 13:47:31 +0000109/** @brief this command is used to look up what authentication, integrity,
110 * confidentiality algorithms are supported.
111 *
112 * @ param ctx - context pointer
113 * @ param channelNumber - channel number
114 * @ param payloadType - payload type
115 * @ param listIndex - list index
116 * @ param algoSelectBit - list algorithms
117 *
118 * @returns ipmi completion code plus response data
119 * - rspChannel - channel number for authentication algorithm.
120 * - rspRecords - cipher suite records.
121 **/
122ipmi::RspType<uint8_t, // Channel Number
123 std::vector<uint8_t> // Cipher Records
124 >
125 getChannelCipherSuites(ipmi::Context::ptr ctx, uint4_t channelNumber,
126 uint4_t reserved1, uint8_t payloadType,
127 uint6_t listIndex, uint1_t reserved2,
128 uint1_t algoSelectBit)
Tom Joseph7cbe2282018-03-21 21:17:33 +0530129{
Richard Marian Thomaiyarf301f042019-01-16 15:56:16 +0530130 static std::vector<uint8_t> cipherRecords;
131 static std::vector<uint8_t> supportedAlgorithms;
Tom Joseph7cbe2282018-03-21 21:17:33 +0530132 static auto recordInit = false;
133
Ayushi Smriti5c3b72c2019-08-30 13:47:31 +0000134 uint8_t rspChannel = ipmi::convertCurrentChannelNum(
135 static_cast<uint8_t>(channelNumber), ctx->channel);
Tom Joseph7cbe2282018-03-21 21:17:33 +0530136
Ayushi Smriti5c3b72c2019-08-30 13:47:31 +0000137 if (!ipmi::isValidChannel(rspChannel) || reserved1 != 0 || reserved2 != 0)
Tom Joseph7cbe2282018-03-21 21:17:33 +0530138 {
Ayushi Smriti5c3b72c2019-08-30 13:47:31 +0000139 return ipmi::responseInvalidFieldRequest();
Tom Joseph7cbe2282018-03-21 21:17:33 +0530140 }
jayaprakash Mutyala69daefa2019-10-03 19:36:49 +0000141 if (!ipmi::isValidPayloadType(static_cast<ipmi::PayloadType>(payloadType)))
142 {
George Liu05e93872024-07-17 14:48:14 +0800143 lg2::debug("Get channel cipher suites - Invalid payload type");
George Liucc96b422025-07-08 14:18:48 +0800144 return ipmi::responsePayloadTypeNotSupported();
jayaprakash Mutyala69daefa2019-10-03 19:36:49 +0000145 }
Tom Joseph7cbe2282018-03-21 21:17:33 +0530146
Tom Joseph7cbe2282018-03-21 21:17:33 +0530147 if (!recordInit)
148 {
149 try
150 {
Patrick Williams1318a5e2024-08-16 15:19:54 -0400151 std::tie(cipherRecords, supportedAlgorithms) =
152 cipher::getCipherRecords();
Tom Joseph7cbe2282018-03-21 21:17:33 +0530153 recordInit = true;
154 }
Patrick Venture0b02be92018-08-31 11:55:55 -0700155 catch (const std::exception& e)
Tom Joseph7cbe2282018-03-21 21:17:33 +0530156 {
Ayushi Smriti5c3b72c2019-08-30 13:47:31 +0000157 return ipmi::responseUnspecifiedError();
Tom Joseph7cbe2282018-03-21 21:17:33 +0530158 }
159 }
160
Patrick Williams1318a5e2024-08-16 15:19:54 -0400161 const std::vector<uint8_t>& records =
162 algoSelectBit ? cipherRecords : supportedAlgorithms;
Ayushi Smriti5c3b72c2019-08-30 13:47:31 +0000163 static constexpr auto respSize = 16;
Richard Marian Thomaiyarf301f042019-01-16 15:56:16 +0530164
Ayushi Smritid7dadc22019-09-03 11:43:45 +0530165 // Session support is available in active LAN channels.
166 if ((ipmi::getChannelSessionSupport(rspChannel) ==
167 ipmi::EChannelSessSupported::none) ||
168 !(ipmi::doesDeviceExist(rspChannel)))
169 {
George Liu05e93872024-07-17 14:48:14 +0800170 lg2::debug("Get channel cipher suites - Device does not exist");
Ayushi Smritid7dadc22019-09-03 11:43:45 +0530171 return ipmi::responseInvalidFieldRequest();
172 }
173
Tom Joseph7cbe2282018-03-21 21:17:33 +0530174 // List index(00h-3Fh), 0h selects the first set of 16, 1h selects the next
175 // set of 16 and so on.
Tom Joseph7cbe2282018-03-21 21:17:33 +0530176
177 // Calculate the number of record data bytes to be returned.
Patrick Williams1318a5e2024-08-16 15:19:54 -0400178 auto start =
179 std::min(static_cast<size_t>(listIndex) * respSize, records.size());
Ayushi Smriti5c3b72c2019-08-30 13:47:31 +0000180 auto end = std::min((static_cast<size_t>(listIndex) * respSize) + respSize,
181 records.size());
Tom Joseph7cbe2282018-03-21 21:17:33 +0530182 auto size = end - start;
183
Ayushi Smriti5c3b72c2019-08-30 13:47:31 +0000184 std::vector<uint8_t> rspRecords;
185 std::copy_n(records.data() + start, size, std::back_inserter(rspRecords));
Tom Joseph7cbe2282018-03-21 21:17:33 +0530186
Ayushi Smriti5c3b72c2019-08-30 13:47:31 +0000187 return ipmi::responseSuccess(rspChannel, rspRecords);
Tom Joseph7cbe2282018-03-21 21:17:33 +0530188}