36 lines
1.2 KiB
C++
36 lines
1.2 KiB
C++
|
#include <memory>
|
||
|
#include <stdexcept>
|
||
|
|
||
|
#include <openssl/hmac.h>
|
||
|
#include <openssl/rand.h>
|
||
|
#include "openssl_wrapper.h"
|
||
|
|
||
|
std::vector<char> secure_random_bytes(int num) {
|
||
|
if (num < 0) {
|
||
|
throw std::invalid_argument("secure_random_bytes(): num variable out of range (num < 0)");
|
||
|
}
|
||
|
|
||
|
std::vector<char> bytes(static_cast<size_t>(num), 0);
|
||
|
if (RAND_bytes(reinterpret_cast<unsigned char*>(bytes.data()), num) == 1) {
|
||
|
return bytes;
|
||
|
} else {
|
||
|
throw OpenSSLException(ERR_get_error());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
std::array<char, 32> hmac_sha3_256(const std::vector<char>& key, const std::vector<char>& data) {
|
||
|
char hmac[32];
|
||
|
unsigned int md_len;
|
||
|
|
||
|
std::unique_ptr<EVP_MD, decltype(&EVP_MD_free)> md(EVP_MD_fetch(nullptr, "SHA3-256", nullptr), EVP_MD_free);
|
||
|
if (HMAC(md.get(), key.data(), static_cast<int>(key.size()), reinterpret_cast<const unsigned char*>(data.data()), data.size(), reinterpret_cast<unsigned char*>(hmac), &md_len)) {
|
||
|
if (md_len != 32) {
|
||
|
throw std::runtime_error("hmac_sha3_256(): HMAC() returned an unexpected size");
|
||
|
}
|
||
|
|
||
|
return std::to_array(hmac);
|
||
|
} else {
|
||
|
throw OpenSSLException(ERR_get_error());
|
||
|
}
|
||
|
}
|