blob: 350b29f62dd1ae2c04cba02e3e81a4e44b40ea34 [file] [log] [blame]
// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#pragma once
#include <stddef.h>
#include <stdint.h>
#include <fbl/macros.h>
#include <fbl/unique_ptr.h>
#include <zircon/types.h>
// |crypto::Bytes| is a small helper class that simply wraps a buffer. It saves on some boilerplate
// when allocating a buffer. More importantly, when going out of scope, the destructor guarantees
// that the buffer will be zeroed in a way that will not be optimized away. Any buffer that holds
// cryptographically sensitive random data should be a |Bytes| and get its data via a call to
// |Bytes::Randomize|.
namespace crypto {
class Bytes final {
public:
Bytes();
~Bytes();
// Accessors
const uint8_t* get() const { return buf_.get(); }
uint8_t* get() { return buf_.get(); }
size_t len() const { return len_; }
// Resets self and then takes ownership of the given |buf| of |len| bytes.
void Adopt(fbl::unique_ptr<uint8_t[]> buf, size_t len);
// Discards the current contents and allocates a new buffer of |size| bytes initialized to the
// given |fill| value.
zx_status_t Init(size_t size, uint8_t fill = 0);
// Resize the underlying buffer. If the new length is shorter, the data is truncated. If it is
// longer, it is padded with the given |fill| value.
zx_status_t Resize(size_t size, uint8_t fill = 0);
// Copies |len| bytes from |buf| to the underlying buffer, starting at |off|. Resizes the
// buffer as needed.
zx_status_t Copy(const void* buf, size_t len, zx_off_t off = 0);
// Resizes the the underlying buffer to |size| and fills it with random data.
zx_status_t Randomize(size_t size);
// Treats the contents of this object as a (big-endian) arbitrary precision unsigned integer and
// increments it. Returns |ZX_ERR_OUT_OF_RANGE| if incrementing would overflow.
zx_status_t Increment();
// Yields ownership of the underlying buffer and returns it after saving the length in |len| if
// not null.
fbl::unique_ptr<uint8_t[]> Release(size_t* len = nullptr);
// Clears all state from this instance. This is guaranteed to zeroize and free the underlying
// buffer if it is allocated.
void Reset();
// Array access operators. Assert that |off| is not out of bounds.
const uint8_t& operator[](zx_off_t off) const;
uint8_t& operator[](zx_off_t off);
// Comparison operators. These are guaranteed to be constant-time.
bool operator==(const Bytes& other) const;
bool operator!=(const Bytes& other) const { return !(*this == other); }
private:
DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(Bytes);
// The underlying buffer. The destructor is guaranteed to zero this buffer if allocated.
fbl::unique_ptr<uint8_t[]> buf_;
// Length in bytes of memory currently allocated to the underlying buffer.
size_t len_;
};
} // namespace crypto