tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

vqsort.cc (3737B)


      1 // Copyright 2021 Google LLC
      2 // SPDX-License-Identifier: Apache-2.0
      3 //
      4 // Licensed under the Apache License, Version 2.0 (the "License");
      5 // you may not use this file except in compliance with the License.
      6 // You may obtain a copy of the License at
      7 //
      8 //      http://www.apache.org/licenses/LICENSE-2.0
      9 //
     10 // Unless required by applicable law or agreed to in writing, software
     11 // distributed under the License is distributed on an "AS IS" BASIS,
     12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13 // See the License for the specific language governing permissions and
     14 // limitations under the License.
     15 
     16 #include "hwy/contrib/sort/vqsort.h"
     17 
     18 #include "hwy/base.h"
     19 #include "hwy/contrib/sort/vqsort-inl.h"
     20 #include "hwy/per_target.h"
     21 
     22 // Check if we have getrandom from <sys/random.h>. Because <features.h> is
     23 // unavailable on Android and non-Linux RVV, we assume that those systems lack
     24 // getrandom. Note that the only supported sources of entropy are getrandom or
     25 // Windows, thus VQSORT_SECURE_SEED=0 when this is 0 and we are not on Windows.
     26 #if defined(ANDROID) || defined(__ANDROID__) || \
     27    (HWY_ARCH_RISCV && !HWY_OS_LINUX)
     28 #define VQSORT_GETRANDOM 0
     29 #endif
     30 
     31 #if !defined(VQSORT_GETRANDOM) && HWY_OS_LINUX
     32 #include <features.h>
     33 
     34 // ---- which libc
     35 #if defined(__UCLIBC__)
     36 #define VQSORT_GETRANDOM 1  // added Mar 2015, before uclibc-ng 1.0
     37 
     38 #elif defined(__GLIBC__) && defined(__GLIBC_PREREQ)
     39 #if __GLIBC_PREREQ(2, 25)
     40 #define VQSORT_GETRANDOM 1
     41 #else
     42 #define VQSORT_GETRANDOM 0
     43 #endif
     44 
     45 #else
     46 // Assume MUSL, which has getrandom since 2018. There is no macro to test, see
     47 // https://www.openwall.com/lists/musl/2013/03/29/13.
     48 #define VQSORT_GETRANDOM 1
     49 
     50 #endif  // ---- which libc
     51 #endif  // linux
     52 
     53 #if !defined(VQSORT_GETRANDOM)
     54 #define VQSORT_GETRANDOM 0
     55 #endif
     56 
     57 // Choose a seed source for SFC generator: 1=getrandom, 2=CryptGenRandom.
     58 // Allow user override - not all Android support the getrandom wrapper.
     59 #ifndef VQSORT_SECURE_SEED
     60 
     61 #if VQSORT_GETRANDOM
     62 #define VQSORT_SECURE_SEED 1
     63 #elif defined(_WIN32) || defined(_WIN64)
     64 #define VQSORT_SECURE_SEED 2
     65 #else
     66 #define VQSORT_SECURE_SEED 0
     67 #endif
     68 
     69 #endif  // VQSORT_SECURE_SEED
     70 
     71 // Pull in dependencies of the chosen seed source.
     72 #if VQSORT_SECURE_SEED == 1
     73 #include <sys/random.h>
     74 #elif VQSORT_SECURE_SEED == 2
     75 #ifndef NOMINMAX
     76 #define NOMINMAX
     77 #endif  // NOMINMAX
     78 #ifndef WIN32_LEAN_AND_MEAN
     79 #define WIN32_LEAN_AND_MEAN
     80 #endif  // WIN32_LEAN_AND_MEAN
     81 #include <windows.h>
     82 #if HWY_COMPILER_MSVC || HWY_COMPILER_CLANGCL
     83 #pragma comment(lib, "advapi32.lib")
     84 #endif  // HWY_COMPILER_MSVC || HWY_COMPILER_CLANGCL
     85 // Must come after windows.h.
     86 #include <wincrypt.h>
     87 #endif  // VQSORT_SECURE_SEED
     88 
     89 namespace hwy {
     90 
     91 // Returns false or performs the equivalent of `memcpy(bytes, r, 16)`, where r
     92 // is high-quality (unpredictable, uniformly distributed) random bits.
     93 bool Fill16BytesSecure(void* bytes) {
     94 #if VQSORT_SECURE_SEED == 1
     95  // May block if urandom is not yet initialized.
     96  const ssize_t ret = getrandom(bytes, 16, /*flags=*/0);
     97  if (ret == 16) return true;
     98 #elif VQSORT_SECURE_SEED == 2
     99  HCRYPTPROV hProvider{};
    100  if (CryptAcquireContextA(&hProvider, nullptr, nullptr, PROV_RSA_FULL,
    101                           CRYPT_VERIFYCONTEXT)) {
    102    const BOOL ok =
    103        CryptGenRandom(hProvider, 16, reinterpret_cast<BYTE*>(bytes));
    104    CryptReleaseContext(hProvider, 0);
    105    if (ok) return true;
    106  }
    107 #else
    108  (void)bytes;
    109 #endif
    110 
    111  return false;
    112 }
    113 
    114 // Unused, only for ABI compatibility
    115 void Sorter::Fill24Bytes(const void*, size_t, void*) {}
    116 bool Sorter::HaveFloat64() { return hwy::HaveFloat64(); }
    117 Sorter::Sorter() {}
    118 void Sorter::Delete() {}
    119 uint64_t* GetGeneratorState() { return hwy::detail::GetGeneratorStateStatic(); }
    120 
    121 }  // namespace hwy