Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
/*!
* \file hmac.hh
* \brief Header file for HMAC helper methods.
* \author ETSI STF525
* \copyright ETSI Copyright Notification
* No part may be reproduced except as authorized by written permission.
* The copyright and the foregoing restriction extend to reproduction in all media.
* All rights reserved.
* \version 0.1
*/
#pragma once
#include <vector>
#include <openssl/hmac.h>
#include <openssl/objects.h>
/*!
* \enum Supported hash algorithms
*/
enum class hash_algorithms: unsigned char {
sha_256, /*!< HMAC with SHA-256 */
sha_384 /*!< HMAC with SHA-384 */
}; // End of class hash_algorithms
/*!
* \class hmac
* \brief This class provides description of HMAC helper methods
*/
class hmac {
HMAC_CTX _ctx; //! HMAC context
hash_algorithms _hash_algorithms;
public:
/*!
* \brief Default constructor
* Create a new instance of the hmac class
* \param[in] p_hash_algorithms The hash algorithm to be used to compute the HMAC
*/
hmac(const hash_algorithms p_hash_algorithms): _ctx{}, _hash_mod(p_hash_algorithms) { ::HMAC_CTX_init(&_ctx); };
/*!
* \brief Default destructor
*/
virtual ~hmac() { ::HMAC_CTX_cleanup(&_ctx); };
/*!
* \inline
* \fn int generate(const std::vector<unsigned char> p_buffer, const std::vector<unsigned char> p_secret_key, std::vector<unsigned char>& p_hmac);
* \brief Receive bytes formated data from the lower layers
* \param[in] p_buffer The data used to generate the HMAC
* \param[in] p_secret_key The secret key to used to generate the HMAC
* \param[out] p_hmac The HMAC value based of the provided data
* \return 0 on success, -1 otherwise
*/
inline int generate(const std::vector<unsigned char> p_buffer, const std::vector<unsigned char> p_secret_key, std::vector<unsigned char>& p_hmac) {
// Sanity check
if (p_buffer.size() == 0) {
return -1;
}
return generate(p_buffer.data(), p_buffer.size(), p_secret_key.data(), p_secret_key.size(), p_hmac);
};
/*!
* \inline
* \fn int generate(const unsigned char *p_buffer, const size_t p_buffer_length, const unsigned char *p_secret_key, const size_t p_secret_key_length, std::vector<unsigned char>& p_hmac);
* \brief Receive bytes formated data from the lower layers
* \param[in] p_buffer The data used to generate the HMAC
* \param[in] p_buffer_length The size of the data
* \param[in] p_secret_key The secret key to used to generate the HMAC
* \param[in] p_secret_key_length The size of the secret key
* \param[out] p_hmac The HMAC value based of the provided data
* \return 0 on success, -1 otherwise
*/
inline int generate(const unsigned char *p_buffer, const size_t p_buffer_length, const unsigned char *p_secret_key, const size_t p_secret_key_length, std::vector<unsigned char>& p_hmac) {
// Sanity check
if ((p_buffer == nullptr) || (p_secret_key == nullptr)) {
return -1;
}
if (_hash_mod == hash_algorithms::sha_256) {
// Resize data buffer
p_hmac.resize(64);
// Compute the hash value
::HMAC_Init_ex(&_ctx, p_secret_key_length, EVP_sha256(), NULL);
::HMAC_Update(&_ctx, p_buffer, p_length);
::HMAC_Final(&_ctx, static_cast<unsigned char*>(p_hmac.data()));
} else if (_hash_mod == hash_algorithms::sha_512) {
// Resize data buffer
p_hmac.resize(128);
// Compute the hash value
::HMAC_Init_ex(&_ctx, p_secret_key_length, EVP_sha512(), NULL);
::HMAC_Update(&_ctx, p_buffer, p_length);
::HMAC_Final(&_ctx, static_cast<unsigned char*>(p_hmac.data()));
} else { // TODO To be continued
return -1;
}
return 0;
};
}; // End of class hmac