blob: a9057787f7ff90c71cd6a4cef9ef6e0cd53b40a3 [file] [log] [blame]
Tom Joseph8c0446c2016-08-05 07:13:07 -05001#pragma once
2
3#include <array>
4#include <vector>
5
6namespace cipher
7{
8namespace rakp_auth
9{
10
11constexpr size_t USER_KEY_MAX_LENGTH = 20;
12constexpr size_t BMC_RANDOM_NUMBER_LEN = 16;
13constexpr size_t REMOTE_CONSOLE_RANDOM_NUMBER_LEN = 16;
14
15/*
16 * @enum RAKP Authentication Algorithms
17 *
18 * RMCP+ Authenticated Key-Exchange Protocol (RAKP)
19 *
20 * RAKP-None is not supported as per the following recommendation
21 * (https://www.us-cert.gov/ncas/alerts/TA13-207A)
22 * ("cipher 0" is an option enabled by default on many IPMI enabled devices that
23 * allows authentication to be bypassed. Disable "cipher 0" to prevent
24 * attackers from bypassing authentication and sending arbitrary IPMI commands.)
25 */
26enum class Algorithms : uint8_t
27{
28 RAKP_NONE = 0, // Mandatory
29 RAKP_HMAC_SHA1, // Mandatory
30 RAKP_HMAC_MD5, // Optional
31 RAKP_HMAC_SHA256, // Optional
32 // Reserved used to indicate an invalid authentication algorithm
33 RAKP_HMAC_INVALID = 0xB0
34};
35
36/*
37 * @class Interface
38 *
39 * Interface is the base class for the Authentication Algorithms.
40 * The Authentication Algorithm specifies the type of authentication “handshake”
41 * process that is used and identifies any particular variations of hashing or
42 * signature algorithm that is used as part of the process.
43 *
44 */
45class Interface
46{
47 public:
48 Interface() = default;
49 virtual ~Interface() = default;
50 Interface(const Interface&) = default;
51 Interface& operator=(const Interface&) = default;
52 Interface(Interface&&) = default;
53 Interface& operator=(Interface&&) = default;
54
55 /*
56 * @brief Generate the Hash Message Authentication Code
57 *
58 * This API is invoked to generate the Key Exchange Authentication Code
59 * in the RAKP2 and RAKP4 sequence and for generating the Session
60 * Integrity Key.
61 *
62 * @param input message
63 *
64 * @return hash output
65 *
66 * @note The user key which is the secret key for the hash operation
67 * needs to be set before this operation.
68 */
69 std::vector<uint8_t> virtual generateHMAC(
70 std::vector<uint8_t>& input) const = 0;
71
72 /*
73 * @brief Generate the Integrity Check Value
74 *
75 * This API is invoked in the RAKP4 sequence for generating the
76 * Integrity Check Value.
77 *
78 * @param input message
79 *
80 * @return hash output
81 *
82 * @note The session integrity key which is the secret key for the
83 * hash operation needs to be set before this operation.
84 */
85 std::vector<uint8_t> virtual generateICV(
86 std::vector<uint8_t>& input) const = 0;
87
88 // User Key is hardcoded to PASSW0RD till the IPMI User account
89 // management is in place.
90 std::array<uint8_t, USER_KEY_MAX_LENGTH> userKey = {"PASSW0RD"};
91
92 // Managed System Random Number
93 std::array<uint8_t, BMC_RANDOM_NUMBER_LEN> bmcRandomNum;
94
95 // Remote Console Random Number
96 std::array<uint8_t, REMOTE_CONSOLE_RANDOM_NUMBER_LEN> rcRandomNum;
97
98 // Session Integrity Key
99 std::vector<uint8_t> sessionIntegrityKey;
100};
101
102/*
103 * @class AlgoSHA1
104 *
105 * RAKP-HMAC-SHA1 specifies the use of RAKP messages for the key exchange
106 * portion of establishing the session, and that HMAC-SHA1 (per [RFC2104]) is
107 * used to create 20-byte Key Exchange Authentication Code fields in RAKP
108 * Message 2 and RAKP Message 3. HMAC-SHA1-96(per [RFC2404]) is used for
109 * generating a 12-byte Integrity Check Value field for RAKP Message 4.
110 */
111
112class AlgoSHA1 : public Interface
113{
114 public:
115 AlgoSHA1() = default;
116 ~AlgoSHA1() = default;
117 AlgoSHA1(const AlgoSHA1&) = default;
118 AlgoSHA1& operator=(const AlgoSHA1&) = default;
119 AlgoSHA1(AlgoSHA1&&) = default;
120 AlgoSHA1& operator=(AlgoSHA1&&) = default;
121
122 std::vector<uint8_t> generateHMAC(std::vector<uint8_t>& input) const
123 override;
124
125 std::vector<uint8_t> generateICV(std::vector<uint8_t>& input) const
126 override;
127};
128
129}// namespace auth
130
131}// namespace cipher
132