1*40e9b92eSEd Tanous // SPDX-License-Identifier: Apache-2.0
2*40e9b92eSEd Tanous // SPDX-FileCopyrightText: Copyright OpenBMC Authors
32c6ffdb0SEd Tanous #include "ossl_random.hpp"
42c6ffdb0SEd Tanous
541fe81c2SEd Tanous #include "logging.hpp"
641fe81c2SEd Tanous
741fe81c2SEd Tanous #include <cstddef>
841fe81c2SEd Tanous #include <cstdint>
941fe81c2SEd Tanous #include <string_view>
1041fe81c2SEd Tanous
11b7f3a82bSEd Tanous extern "C"
12b7f3a82bSEd Tanous {
13724985ffSEd Tanous #include <openssl/crypto.h>
14b7f3a82bSEd Tanous #include <openssl/rand.h>
15b7f3a82bSEd Tanous }
16b7f3a82bSEd Tanous
170420885cSEd Tanous #include <boost/uuid/basic_random_generator.hpp>
182c6ffdb0SEd Tanous #include <boost/uuid/uuid_io.hpp>
192c6ffdb0SEd Tanous
20b7f3a82bSEd Tanous #include <array>
21b7f3a82bSEd Tanous #include <random>
22f0b59af4SEd Tanous #include <string>
23f0b59af4SEd Tanous
24b7f3a82bSEd Tanous namespace bmcweb
25b7f3a82bSEd Tanous {
operator ()()26b7f3a82bSEd Tanous uint8_t OpenSSLGenerator::operator()()
27b7f3a82bSEd Tanous {
28b7f3a82bSEd Tanous uint8_t index = 0;
29b7f3a82bSEd Tanous int rc = RAND_bytes(&index, sizeof(index));
30b7f3a82bSEd Tanous if (rc != opensslSuccess)
31b7f3a82bSEd Tanous {
32b7f3a82bSEd Tanous BMCWEB_LOG_ERROR("Cannot get random number");
33b7f3a82bSEd Tanous err = true;
34b7f3a82bSEd Tanous }
35b7f3a82bSEd Tanous
36b7f3a82bSEd Tanous return index;
37b7f3a82bSEd Tanous }
38b7f3a82bSEd Tanous
getRandomUUID()39b7f3a82bSEd Tanous std::string getRandomUUID()
402c6ffdb0SEd Tanous {
412c6ffdb0SEd Tanous using bmcweb::OpenSSLGenerator;
422c6ffdb0SEd Tanous OpenSSLGenerator ossl;
432c6ffdb0SEd Tanous return boost::uuids::to_string(
442c6ffdb0SEd Tanous boost::uuids::basic_random_generator<OpenSSLGenerator>(ossl)());
452c6ffdb0SEd Tanous }
46b7f3a82bSEd Tanous
getRandomIdOfLength(size_t length)47b7f3a82bSEd Tanous std::string getRandomIdOfLength(size_t length)
48b7f3a82bSEd Tanous {
49b7f3a82bSEd Tanous static constexpr std::array<char, 62> alphanum = {
50b7f3a82bSEd Tanous '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C',
51b7f3a82bSEd Tanous 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
52b7f3a82bSEd Tanous 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c',
53b7f3a82bSEd Tanous 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
54b7f3a82bSEd Tanous 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'};
55b7f3a82bSEd Tanous
56b7f3a82bSEd Tanous std::string token;
57b7f3a82bSEd Tanous token.resize(length, '0');
58b7f3a82bSEd Tanous std::uniform_int_distribution<size_t> dist(0, alphanum.size() - 1);
59b7f3a82bSEd Tanous
60b7f3a82bSEd Tanous bmcweb::OpenSSLGenerator gen;
61b7f3a82bSEd Tanous
62b7f3a82bSEd Tanous for (char& tokenChar : token)
63b7f3a82bSEd Tanous {
64b7f3a82bSEd Tanous tokenChar = alphanum[dist(gen)];
65b7f3a82bSEd Tanous if (gen.error())
66b7f3a82bSEd Tanous {
67b7f3a82bSEd Tanous return "";
68b7f3a82bSEd Tanous }
69b7f3a82bSEd Tanous }
70b7f3a82bSEd Tanous return token;
71b7f3a82bSEd Tanous }
72724985ffSEd Tanous
constantTimeStringCompare(std::string_view a,std::string_view b)73724985ffSEd Tanous bool constantTimeStringCompare(std::string_view a, std::string_view b)
74724985ffSEd Tanous {
75724985ffSEd Tanous // Important note, this function is ONLY constant time if the two input
76724985ffSEd Tanous // sizes are the same
77724985ffSEd Tanous if (a.size() != b.size())
78724985ffSEd Tanous {
79724985ffSEd Tanous return false;
80724985ffSEd Tanous }
81724985ffSEd Tanous return CRYPTO_memcmp(a.data(), b.data(), a.size()) == 0;
82724985ffSEd Tanous }
83724985ffSEd Tanous
operator ()(std::string_view a,std::string_view b) const84724985ffSEd Tanous bool ConstantTimeCompare::operator()(std::string_view a,
85724985ffSEd Tanous std::string_view b) const
86724985ffSEd Tanous {
87724985ffSEd Tanous return constantTimeStringCompare(a, b);
88724985ffSEd Tanous }
89724985ffSEd Tanous
90b7f3a82bSEd Tanous } // namespace bmcweb
91