blob: ac06e069ca69a0b09601eade5775406394ce2ed0 [file] [log] [blame]
Tom Joseph77531db2017-01-10 15:44:44 +05301#pragma once
2
3#include <openssl/sha.h>
4#include <array>
5#include <vector>
6
7namespace cipher
8{
9
10namespace integrity
11{
12
13using Buffer = std::vector<uint8_t>;
14using Key = std::array<uint8_t, SHA_DIGEST_LENGTH>;
15
16/*
17 * RSP needs more keying material than can be provided by session integrity key
18 * alone. As a result all keying material for the RSP integrity algorithms
19 * will be generated by processing a pre-defined set of constants using HMAC per
20 * [RFC2104], keyed by SIK. These constants are constructed using a hexadecimal
21 * octet value repeated up to the HMAC block size in length starting with the
22 * constant 01h. This mechanism can be used to derive up to 255
23 * HMAC-block-length pieces of keying material from a single SIK. For the
24 * mandatory integrity algorithm HMAC-SHA1-96, processing the following
25 * constant will generate the required amount of keying material.
26 */
27constexpr Key const1 = { 0x01, 0x01, 0x01, 0x01, 0x01,
28 0x01, 0x01, 0x01, 0x01, 0x01,
29 0x01, 0x01, 0x01, 0x01, 0x01,
30 0x01, 0x01, 0x01, 0x01, 0x01
31 };
32
33/*
34 * @enum Integrity Algorithms
35 *
36 * The Integrity Algorithm Number specifies the algorithm used to generate the
37 * contents for the AuthCode “signature” field that accompanies authenticated
38 * IPMI v2.0/RMCP+ messages once the session has been established. If the
39 * Integrity Algorithm is none the AuthCode value is not calculated and the
40 * AuthCode field in the message is not present.
41 */
42enum class Algorithms : uint8_t
43{
44 NONE, // Mandatory
45 HMAC_SHA1_96, // Mandatory
46 HMAC_MD5_128, // Optional
47 MD5_128, // Optional
48 HMAC_SHA256_128, // Optional
49};
50
51/*
52 * @class Interface
53 *
54 * Interface is the base class for the Integrity Algorithms.
55 * Unless otherwise specified, the integrity algorithm is applied to the packet
56 * data starting with the AuthType/Format field up to and including the field
57 * that immediately precedes the AuthCode field itself.
58 */
59class Interface
60{
61 public:
62 /*
63 * @brief Constructor for Interface
64 *
65 * @param[in] - Session Integrity Key to generate K1
66 * @param[in] - Additional keying material to generate K1
67 * @param[in] - AuthCode length
68 */
69 explicit Interface(const Buffer& sik,
70 const Key& addKey,
71 size_t authLength);
72
73 Interface() = delete;
74 virtual ~Interface() = default;
75 Interface(const Interface&) = default;
76 Interface& operator=(const Interface&) = default;
77 Interface(Interface&&) = default;
78 Interface& operator=(Interface&&) = default;
79
80 /*
81 * @brief Verify the integrity data of the packet
82 *
83 * @param[in] packet - Incoming IPMI packet
84 * @param[in] packetLen - Packet length excluding authCode
85 * @param[in] integrityData - Iterator to the authCode in the packet
86 *
87 * @return true if authcode in the packet is equal to one generated
88 * using integrity algorithm on the packet data, false otherwise
89 */
90 bool virtual verifyIntegrityData(
91 const Buffer& packet,
92 const size_t packetLen,
93 Buffer::const_iterator integrityData) const = 0;
94
95 /*
96 * @brief Generate integrity data for the outgoing IPMI packet
97 *
98 * @param[in] input - Outgoing IPMI packet
99 *
100 * @return authcode for the outgoing IPMI packet
101 *
102 */
103 Buffer virtual generateIntegrityData(const Buffer& input) const = 0;
104
105 /*
106 * AuthCode field length varies based on the integrity algorithm, for
107 * HMAC-SHA1-96 the authcode field is 12 bytes. For HMAC-SHA256-128 and
108 * HMAC-MD5-128 the authcode field is 16 bytes.
109 */
110 size_t authCodeLength;
111
112 protected:
113
114 // K1 key used to generated the integrity data
115 Key K1;
116};
117
Tom Josephd212a6d2017-01-10 15:48:40 +0530118/*
119 * @class AlgoSHA1
120 *
121 * @brief Implementation of the HMAC-SHA1-96 Integrity algorithm
122 *
123 * HMAC-SHA1-96 take the Session Integrity Key and use it to generate K1. K1 is
124 * then used as the key for use in HMAC to produce the AuthCode field.
125 * For “one-key” logins, the user’s key (password) is used in the creation of
126 * the Session Integrity Key. When the HMAC-SHA1-96 Integrity Algorithm is used
127 * the resulting AuthCode field is 12 bytes (96 bits).
128 */
129class AlgoSHA1 final : public Interface
130{
131 public:
132 static constexpr size_t SHA1_96_AUTHCODE_LENGTH = 12;
133
134 /*
135 * @brief Constructor for AlgoSHA1
136 *
137 * @param[in] - Session Integrity Key
138 */
139 explicit AlgoSHA1(const Buffer& sik) :
140 Interface(sik, const1, SHA1_96_AUTHCODE_LENGTH) {}
141
142 AlgoSHA1() = delete;
143 ~AlgoSHA1() = default;
144 AlgoSHA1(const AlgoSHA1&) = default;
145 AlgoSHA1& operator=(const AlgoSHA1&) = default;
146 AlgoSHA1(AlgoSHA1&&) = default;
147 AlgoSHA1& operator=(AlgoSHA1&&) = default;
148
149 /*
150 * @brief Verify the integrity data of the packet
151 *
152 * @param[in] packet - Incoming IPMI packet
153 * @param[in] length - Length of the data in the packet to calculate
154 * the integrity data
155 * @param[in] integrityData - Iterator to the authCode in the packet
156 *
157 * @return true if authcode in the packet is equal to one generated
158 * using integrity algorithm on the packet data, false otherwise
159 */
160 bool verifyIntegrityData(
161 const Buffer& packet,
162 const size_t length,
163 Buffer::const_iterator integrityData) const override;
164
165 /*
166 * @brief Generate integrity data for the outgoing IPMI packet
167 *
168 * @param[in] input - Outgoing IPMI packet
169 *
170 * @return on success return the integrity data for the outgoing IPMI
171 * packet
172 */
173 Buffer generateIntegrityData(const Buffer& packet) const override;
174
175 private:
176 /*
177 * @brief Generate HMAC based on HMAC-SHA1-96 algorithm
178 *
179 * @param[in] input - pointer to the message
180 * @param[in] length - length of the message
181 *
182 * @return on success returns the message authentication code
183 *
184 */
185 Buffer generateHMAC(const uint8_t* input, const size_t len) const;
186};
187
Tom Joseph77531db2017-01-10 15:44:44 +0530188}// namespace integrity
189
190}// namespace cipher
191