tor-browser

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

GeneratePlaceholderCanvasData.h (3243B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #ifndef mozilla_dom_GeneratePlaceholderCanvasData_h
      8 #define mozilla_dom_GeneratePlaceholderCanvasData_h
      9 
     10 #include "mozilla/StaticPrefs_privacy.h"
     11 #include "nsCOMPtr.h"
     12 #include "nsIRandomGenerator.h"
     13 #include "nsServiceManagerUtils.h"
     14 
     15 #define RANDOM_BYTES_TO_SAMPLE 32
     16 
     17 namespace mozilla::dom {
     18 
     19 /**
     20 * This function tries to generate random data for placeholder canvas by
     21 * sampling RANDOM_BYTES_TO_SAMPLE bytes and then returning it. If it fails,
     22 * returns nullptr.
     23 *
     24 * @return uint8_t*  output buffer
     25 */
     26 inline uint8_t* TryToGenerateRandomDataForPlaceholderCanvasData() {
     27  nsresult rv;
     28  nsCOMPtr<nsIRandomGenerator> rg =
     29      do_GetService("@mozilla.org/security/random-generator;1", &rv);
     30  if (NS_FAILED(rv)) {
     31    return nullptr;
     32  }
     33  uint8_t* randomData;
     34  rv = rg->GenerateRandomBytes(RANDOM_BYTES_TO_SAMPLE, &randomData);
     35  if (NS_FAILED(rv)) {
     36    return nullptr;
     37  }
     38  return randomData;
     39 }
     40 
     41 /**
     42 * If randomData not nullptr, repeats those bytes many times to fill buffer. If
     43 * randomData is nullptr, returns all-white pixel data.
     44 *
     45 * @param[in]   randomData  Buffer of RANDOM_BYTES_TO_SAMPLE bytes of random
     46 *                          data, or nullptr
     47 * @param[in]   size        Size of output buffer
     48 * @param[out]  buffer      Output buffer
     49 */
     50 inline void FillPlaceholderCanvas(uint8_t* randomData, uint32_t size,
     51                                  uint8_t* buffer) {
     52  if (!randomData) {
     53    memset(buffer, 0xFF, size);
     54    return;
     55  }
     56  auto remaining_to_fill = size;
     57  auto index = 0;
     58  while (remaining_to_fill > 0) {
     59    auto bytes_to_write = (remaining_to_fill > RANDOM_BYTES_TO_SAMPLE)
     60                              ? RANDOM_BYTES_TO_SAMPLE
     61                              : remaining_to_fill;
     62    memcpy(buffer + (index * RANDOM_BYTES_TO_SAMPLE), randomData,
     63           bytes_to_write);
     64    remaining_to_fill -= bytes_to_write;
     65    index++;
     66  }
     67  free(randomData);
     68 }
     69 
     70 /**
     71 * When privacy.resistFingerprinting.randomDataOnCanvasExtract is true, tries
     72 * to generate random canvas data by sampling RANDOM_BYTES_TO_SAMPLE bytes and
     73 * then repeating those bytes many times to fill the buffer. If this fails or
     74 * if privacy.resistFingerprinting.randomDataOnCanvasExtract is false, returns
     75 * all-white, opaque pixel data.
     76 *
     77 * It is recommended that callers call this function instead of individually
     78 * calling TryToGenerateRandomDataForPlaceholderCanvasData and
     79 * FillPlaceholderCanvas unless there are requirements, like NoGC, that prevent
     80 * them from calling the RNG service inside this function.
     81 *
     82 * @param[in]   size    Size of output buffer
     83 * @param[out]  buffer  Output buffer
     84 */
     85 inline void GeneratePlaceholderCanvasData(uint32_t size, uint8_t* buffer) {
     86  uint8_t* randomData = TryToGenerateRandomDataForPlaceholderCanvasData();
     87  FillPlaceholderCanvas(randomData, size, buffer);
     88 }
     89 
     90 }  // namespace mozilla::dom
     91 
     92 #endif  // mozilla_dom_GeneratePlaceholderCanvasData_h