xref: /openbmc/phosphor-net-ipmid/auth_algo.hpp (revision 33503e2a90d5615a11ec2d27961ffdefc3a5cd10)
18c0446c1STom Joseph #pragma once
28c0446c1STom Joseph 
3ba11f792STom Joseph #include "crypt_algo.hpp"
4dd1be1a2STom Joseph #include "integrity_algo.hpp"
58c0446c1STom Joseph 
69e801a2bSVernon Mauery #include <array>
79d9b7638SAndrew Geissler #include <cstddef>
87408e76aSAndrew Geissler #include <string>
99e801a2bSVernon Mauery #include <vector>
109e801a2bSVernon Mauery 
118c0446c1STom Joseph namespace cipher
128c0446c1STom Joseph {
138c0446c1STom Joseph namespace rakp_auth
148c0446c1STom Joseph {
158c0446c1STom Joseph constexpr size_t USER_KEY_MAX_LENGTH = 20;
168c0446c1STom Joseph constexpr size_t BMC_RANDOM_NUMBER_LEN = 16;
178c0446c1STom Joseph constexpr size_t REMOTE_CONSOLE_RANDOM_NUMBER_LEN = 16;
188c0446c1STom Joseph 
193563f8feSTom Joseph /**
208c0446c1STom Joseph  * @enum RAKP Authentication Algorithms
218c0446c1STom Joseph  *
228c0446c1STom Joseph  * RMCP+ Authenticated Key-Exchange Protocol (RAKP)
238c0446c1STom Joseph  *
248c0446c1STom Joseph  * RAKP-None is not supported as per the following recommendation
258c0446c1STom Joseph  * (https://www.us-cert.gov/ncas/alerts/TA13-207A)
268c0446c1STom Joseph  * ("cipher 0" is an option enabled by default on many IPMI enabled devices that
278c0446c1STom Joseph  * allows authentication to be bypassed.  Disable "cipher 0" to prevent
288c0446c1STom Joseph  * attackers from bypassing authentication and sending arbitrary IPMI commands.)
298c0446c1STom Joseph  */
308c0446c1STom Joseph enum class Algorithms : uint8_t
318c0446c1STom Joseph {
32fe5a6458STom Joseph     RAKP_NONE = 0,    // Mandatory (implemented, not supported)
33fe5a6458STom Joseph     RAKP_HMAC_SHA1,   // Mandatory (implemented, default choice in ipmitool)
34fe5a6458STom Joseph     RAKP_HMAC_MD5,    // Optional (not implemented)
35fe5a6458STom Joseph     RAKP_HMAC_SHA256, // Optional (implemented, best available)
368c0446c1STom Joseph     // Reserved used to indicate an invalid authentication algorithm
378c0446c1STom Joseph     RAKP_HMAC_INVALID = 0xB0
388c0446c1STom Joseph };
398c0446c1STom Joseph 
403563f8feSTom Joseph /**
418c0446c1STom Joseph  * @class Interface
428c0446c1STom Joseph  *
438c0446c1STom Joseph  * Interface is the base class for the Authentication Algorithms.
448c0446c1STom Joseph  * The Authentication Algorithm specifies the type of authentication “handshake”
458c0446c1STom Joseph  * process that is used and identifies any particular variations of hashing or
468c0446c1STom Joseph  * signature algorithm that is used as part of the process.
478c0446c1STom Joseph  *
488c0446c1STom Joseph  */
498c0446c1STom Joseph class Interface
508c0446c1STom Joseph {
518c0446c1STom Joseph   public:
Interface(integrity::Algorithms intAlgo,crypt::Algorithms cryptAlgo)52ba11f792STom Joseph     explicit Interface(integrity::Algorithms intAlgo,
53ba11f792STom Joseph                        crypt::Algorithms cryptAlgo) :
548425624aSPatrick Williams         intAlgo(intAlgo), cryptAlgo(cryptAlgo)
55bc8958feSGeorge Liu     {}
56ba11f792STom Joseph 
57dd1be1a2STom Joseph     Interface() = delete;
588c0446c1STom Joseph     virtual ~Interface() = default;
598c0446c1STom Joseph     Interface(const Interface&) = default;
608c0446c1STom Joseph     Interface& operator=(const Interface&) = default;
618c0446c1STom Joseph     Interface(Interface&&) = default;
628c0446c1STom Joseph     Interface& operator=(Interface&&) = default;
638c0446c1STom Joseph 
643563f8feSTom Joseph     /**
658c0446c1STom Joseph      * @brief Generate the Hash Message Authentication Code
668c0446c1STom Joseph      *
678c0446c1STom Joseph      * This API is invoked to generate the Key Exchange Authentication Code
688c0446c1STom Joseph      * in the RAKP2 and RAKP4 sequence and for generating the Session
698c0446c1STom Joseph      * Integrity Key.
708c0446c1STom Joseph      *
718c0446c1STom Joseph      * @param input message
728c0446c1STom Joseph      *
738c0446c1STom Joseph      * @return hash output
748c0446c1STom Joseph      *
758c0446c1STom Joseph      * @note The user key which is the secret key for the hash operation
768c0446c1STom Joseph      *        needs to be set before this operation.
778c0446c1STom Joseph      */
788c0446c1STom Joseph     std::vector<uint8_t> virtual generateHMAC(
7970fd29cfSVernon Mauery         const std::vector<uint8_t>& input) const = 0;
808c0446c1STom Joseph 
813563f8feSTom Joseph     /**
828c0446c1STom Joseph      * @brief Generate the Integrity Check Value
838c0446c1STom Joseph      *
848c0446c1STom Joseph      * This API is invoked in the RAKP4 sequence for generating the
858c0446c1STom Joseph      * Integrity Check Value.
868c0446c1STom Joseph      *
878c0446c1STom Joseph      * @param input message
888c0446c1STom Joseph      *
898c0446c1STom Joseph      * @return hash output
908c0446c1STom Joseph      *
918c0446c1STom Joseph      * @note The session integrity key which is the secret key for the
928c0446c1STom Joseph      *        hash operation needs to be set before this operation.
938c0446c1STom Joseph      */
948c0446c1STom Joseph     std::vector<uint8_t> virtual generateICV(
9570fd29cfSVernon Mauery         const std::vector<uint8_t>& input) const = 0;
968c0446c1STom Joseph 
979b307be6SVernon Mauery     /**
989b307be6SVernon Mauery      * @brief Check if the Authentication algorithm is supported
999b307be6SVernon Mauery      *
1009b307be6SVernon Mauery      * @param[in] algo - authentication algorithm
1019b307be6SVernon Mauery      *
1029b307be6SVernon Mauery      * @return true if algorithm is supported else false
1039b307be6SVernon Mauery      *
1049b307be6SVernon Mauery      */
isAlgorithmSupported(Algorithms algo)1059b307be6SVernon Mauery     static bool isAlgorithmSupported(Algorithms algo)
1069b307be6SVernon Mauery     {
1074c494398SSuryakanth Sekar         if (algo == Algorithms::RAKP_HMAC_SHA256)
1089b307be6SVernon Mauery         {
1099b307be6SVernon Mauery             return true;
1109b307be6SVernon Mauery         }
1119b307be6SVernon Mauery         else
1129b307be6SVernon Mauery         {
1139b307be6SVernon Mauery             return false;
1149b307be6SVernon Mauery         }
1159b307be6SVernon Mauery     }
1169b307be6SVernon Mauery 
1178c0446c1STom Joseph     // User Key is hardcoded to PASSW0RD till the IPMI User account
1188c0446c1STom Joseph     // management is in place.
119e2e97660STom Joseph     std::array<uint8_t, USER_KEY_MAX_LENGTH> userKey = {"0penBmc"};
1208c0446c1STom Joseph 
1218c0446c1STom Joseph     // Managed System Random Number
1228c0446c1STom Joseph     std::array<uint8_t, BMC_RANDOM_NUMBER_LEN> bmcRandomNum;
1238c0446c1STom Joseph 
1248c0446c1STom Joseph     // Remote Console Random Number
1258c0446c1STom Joseph     std::array<uint8_t, REMOTE_CONSOLE_RANDOM_NUMBER_LEN> rcRandomNum;
1268c0446c1STom Joseph 
1278c0446c1STom Joseph     // Session Integrity Key
1288c0446c1STom Joseph     std::vector<uint8_t> sessionIntegrityKey;
129dd1be1a2STom Joseph 
1303563f8feSTom Joseph     /**
131dd1be1a2STom Joseph      * Integrity Algorithm is activated and set in the session data only
132dd1be1a2STom Joseph      * once the session setup is succeeded in the RAKP34 command. But the
133dd1be1a2STom Joseph      * integrity algorithm is negotiated in the Open Session Request command
134ba11f792STom Joseph      * . So the integrity algorithm successfully negotiated is stored
135ba11f792STom Joseph      * in the authentication algorithm's instance.
136dd1be1a2STom Joseph      */
137dd1be1a2STom Joseph     integrity::Algorithms intAlgo;
138ba11f792STom Joseph 
1393563f8feSTom Joseph     /**
140ba11f792STom Joseph      * Confidentiality Algorithm is activated and set in the session data
141ba11f792STom Joseph      * only once the session setup is succeeded in the RAKP34 command. But
142ba11f792STom Joseph      * the confidentiality algorithm is negotiated in the Open Session
143ba11f792STom Joseph      * Request command. So the confidentiality algorithm successfully
144ba11f792STom Joseph      * negotiated is stored in the authentication algorithm's instance.
145ba11f792STom Joseph      */
146ba11f792STom Joseph     crypt::Algorithms cryptAlgo;
1478c0446c1STom Joseph };
1488c0446c1STom Joseph 
1493563f8feSTom Joseph /**
1508c0446c1STom Joseph  * @class AlgoSHA1
1518c0446c1STom Joseph  *
1528c0446c1STom Joseph  * RAKP-HMAC-SHA1 specifies the use of RAKP messages for the key exchange
1538c0446c1STom Joseph  * portion of establishing the session, and that HMAC-SHA1 (per [RFC2104]) is
1548c0446c1STom Joseph  * used to create 20-byte Key Exchange Authentication Code fields in RAKP
1558c0446c1STom Joseph  * Message 2 and RAKP Message 3. HMAC-SHA1-96(per [RFC2404]) is used for
1568c0446c1STom Joseph  * generating a 12-byte Integrity Check Value field for RAKP Message 4.
1578c0446c1STom Joseph  */
1588c0446c1STom Joseph 
1598c0446c1STom Joseph class AlgoSHA1 : public Interface
1608c0446c1STom Joseph {
1618c0446c1STom Joseph   public:
1622207f51cSVernon Mauery     static constexpr size_t integrityCheckValueLength = 12;
1632207f51cSVernon Mauery 
AlgoSHA1(integrity::Algorithms intAlgo,crypt::Algorithms cryptAlgo)164ba11f792STom Joseph     explicit AlgoSHA1(integrity::Algorithms intAlgo,
165ba11f792STom Joseph                       crypt::Algorithms cryptAlgo) :
1669e801a2bSVernon Mauery         Interface(intAlgo, cryptAlgo)
167bc8958feSGeorge Liu     {}
168ba11f792STom Joseph 
169dd1be1a2STom Joseph     AlgoSHA1() = delete;
1708c0446c1STom Joseph     ~AlgoSHA1() = default;
1718c0446c1STom Joseph     AlgoSHA1(const AlgoSHA1&) = default;
1728c0446c1STom Joseph     AlgoSHA1& operator=(const AlgoSHA1&) = default;
1738c0446c1STom Joseph     AlgoSHA1(AlgoSHA1&&) = default;
1748c0446c1STom Joseph     AlgoSHA1& operator=(AlgoSHA1&&) = default;
1758c0446c1STom Joseph 
176*33503e2aSPatrick Williams     std::vector<uint8_t> generateHMAC(
177*33503e2aSPatrick Williams         const std::vector<uint8_t>& input) const override;
1788c0446c1STom Joseph 
179*33503e2aSPatrick Williams     std::vector<uint8_t> generateICV(
180*33503e2aSPatrick Williams         const std::vector<uint8_t>& input) const override;
1818c0446c1STom Joseph };
1828c0446c1STom Joseph 
1837e9e2ef6SVernon Mauery /**
1847e9e2ef6SVernon Mauery  * @class AlgoSHA256
1857e9e2ef6SVernon Mauery  *
1867e9e2ef6SVernon Mauery  * RAKP-HMAC-SHA256 specifies the use of RAKP messages for the key exchange
1877e9e2ef6SVernon Mauery  * portion of establishing the session, and that HMAC-SHA256 (per [FIPS 180-2]
1887e9e2ef6SVernon Mauery  * and [RFC4634] and is used to create a 32-byte Key Exchange Authentication
1897e9e2ef6SVernon Mauery  * Code fields in RAKP Message 2 and RAKP Message 3. HMAC-SHA256-128 (per
1907e9e2ef6SVernon Mauery  * [RFC4868]) is used for generating a 16-byte Integrity Check Value field for
1917e9e2ef6SVernon Mauery  * RAKP Message 4.
1927e9e2ef6SVernon Mauery  */
1937e9e2ef6SVernon Mauery 
1947e9e2ef6SVernon Mauery class AlgoSHA256 : public Interface
1957e9e2ef6SVernon Mauery {
1967e9e2ef6SVernon Mauery   public:
1977e9e2ef6SVernon Mauery     static constexpr size_t integrityCheckValueLength = 16;
1987e9e2ef6SVernon Mauery 
AlgoSHA256(integrity::Algorithms intAlgo,crypt::Algorithms cryptAlgo)1997e9e2ef6SVernon Mauery     explicit AlgoSHA256(integrity::Algorithms intAlgo,
2007e9e2ef6SVernon Mauery                         crypt::Algorithms cryptAlgo) :
2019e801a2bSVernon Mauery         Interface(intAlgo, cryptAlgo)
202bc8958feSGeorge Liu     {}
2037e9e2ef6SVernon Mauery 
2047e9e2ef6SVernon Mauery     ~AlgoSHA256() = default;
2057e9e2ef6SVernon Mauery     AlgoSHA256(const AlgoSHA256&) = default;
2067e9e2ef6SVernon Mauery     AlgoSHA256& operator=(const AlgoSHA256&) = default;
2077e9e2ef6SVernon Mauery     AlgoSHA256(AlgoSHA256&&) = default;
2087e9e2ef6SVernon Mauery     AlgoSHA256& operator=(AlgoSHA256&&) = default;
2097e9e2ef6SVernon Mauery 
210*33503e2aSPatrick Williams     std::vector<uint8_t> generateHMAC(
211*33503e2aSPatrick Williams         const std::vector<uint8_t>& input) const override;
2127e9e2ef6SVernon Mauery 
213*33503e2aSPatrick Williams     std::vector<uint8_t> generateICV(
214*33503e2aSPatrick Williams         const std::vector<uint8_t>& input) const override;
2157e9e2ef6SVernon Mauery };
2167e9e2ef6SVernon Mauery 
2179e801a2bSVernon Mauery } // namespace rakp_auth
2188c0446c1STom Joseph 
2198c0446c1STom Joseph } // namespace cipher
220