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