xref: /openbmc/bmcweb/src/ossl_random.cpp (revision 40e9b92ec19acffb46f83a6e55b18974da5d708e)
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