tor-browser

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

EncryptedBlock.h (3593B)


      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 file,
      5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #ifndef mozilla_dom_quota_EncryptedBlock_h
      8 #define mozilla_dom_quota_EncryptedBlock_h
      9 
     10 #include <cstdint>
     11 #include <cstring>
     12 #include <limits>
     13 
     14 #include "mozilla/Assertions.h"
     15 #include "mozilla/Span.h"
     16 #include "nsTArray.h"
     17 
     18 namespace mozilla::dom::quota {
     19 
     20 // An encrypted block has the following format:
     21 // - one basic block containing a uint16_t stating the actual payload length
     22 // - one basic block containing the cipher prefix (tyipically a nonce)
     23 // - encrypted payload up to the remainder of the specified overall size
     24 // We currently assume the basic block size is the same as the cipher prefix
     25 // length.
     26 //
     27 // XXX Actually, we don't need the actual payload length in every block. Only
     28 // the last block may be incomplete. The tricky thing is just that it might be
     29 // incomplete by just one or two bytes.
     30 template <size_t CipherPrefixLength, size_t BasicBlockSize>
     31 class EncryptedBlock {
     32 public:
     33  explicit EncryptedBlock(const size_t aOverallSize) {
     34    MOZ_RELEASE_ASSERT(aOverallSize >
     35                       CipherPrefixOffset() + CipherPrefixLength);
     36    MOZ_RELEASE_ASSERT(aOverallSize <= std::numeric_limits<uint16_t>::max());
     37    // XXX Do we need this to be fallible? Then we need a factory/init function.
     38    // But maybe that's not necessary as the block size is not user-provided and
     39    // small.
     40    mData.SetLength(aOverallSize);
     41 
     42    // Bug 1867394: Making sure to zero-initialize first block as there might
     43    // be some unused bytes in it which could expose sensitive data.
     44    // Currently, only sizeof(uint16_t) bytes gets used in the first block.
     45    std::fill(mData.begin(), mData.begin() + CipherPrefixOffset(), 0);
     46    SetActualPayloadLength(MaxPayloadLength());
     47  }
     48 
     49  size_t MaxPayloadLength() const {
     50    return mData.Length() - CipherPrefixLength - CipherPrefixOffset();
     51  }
     52 
     53  void SetActualPayloadLength(uint16_t aActualPayloadLength) {
     54    memcpy(mData.Elements(), &aActualPayloadLength, sizeof(uint16_t));
     55  }
     56  size_t ActualPayloadLength() const {
     57    return *reinterpret_cast<const uint16_t*>(mData.Elements());
     58  }
     59 
     60  using ConstSpan = Span<const uint8_t>;
     61  using MutableSpan = Span<uint8_t>;
     62 
     63  ConstSpan CipherPrefix() const {
     64    return WholeBlock().Subspan(CipherPrefixOffset(), CipherPrefixLength);
     65  }
     66  MutableSpan MutableCipherPrefix() {
     67    return MutableWholeBlock().Subspan(CipherPrefixOffset(),
     68                                       CipherPrefixLength);
     69  }
     70 
     71  ConstSpan Payload() const {
     72    return WholeBlock()
     73        .SplitAt(CipherPrefixOffset() + CipherPrefixLength)
     74        .second.First(RoundedUpToBasicBlockSize(ActualPayloadLength()));
     75  }
     76  MutableSpan MutablePayload() {
     77    return MutableWholeBlock()
     78        .SplitAt(CipherPrefixOffset() + CipherPrefixLength)
     79        .second.First(RoundedUpToBasicBlockSize(ActualPayloadLength()));
     80  }
     81 
     82  ConstSpan WholeBlock() const { return mData; }
     83  MutableSpan MutableWholeBlock() { return mData; }
     84 
     85 private:
     86  static constexpr size_t CipherPrefixOffset() {
     87    return RoundedUpToBasicBlockSize(sizeof(uint16_t));
     88  }
     89 
     90  static constexpr size_t RoundedUpToBasicBlockSize(const size_t aValue) {
     91    return (aValue + BasicBlockSize - 1) / BasicBlockSize * BasicBlockSize;
     92  }
     93 
     94  nsTArray<uint8_t> mData;
     95 };
     96 
     97 }  // namespace mozilla::dom::quota
     98 
     99 #endif