1 // Copyright 2017 The Fuchsia Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #pragma once 6 7 #include <stddef.h> 8 #include <stdint.h> 9 10 #include <fbl/macros.h> 11 #include <fbl/unique_ptr.h> 12 #include <zircon/types.h> 13 14 // |crypto::Bytes| is a small helper class that simply wraps a buffer. It saves on some boilerplate 15 // when allocating a buffer. More importantly, when going out of scope, the destructor guarantees 16 // that the buffer will be zeroed in a way that will not be optimized away. Any buffer that holds 17 // cryptographically sensitive random data should be a |Bytes| and get its data via a call to 18 // |Bytes::Randomize|. 19 namespace crypto { 20 21 class Bytes final { 22 public: 23 Bytes(); 24 ~Bytes(); 25 26 // Accessors get()27 const uint8_t* get() const { return buf_.get(); } get()28 uint8_t* get() { return buf_.get(); } len()29 size_t len() const { return len_; } 30 31 // Resizes the underlying buffer to |len| bytes and fills it with random data. Randomize()32 zx_status_t Randomize() { return Randomize(len_); } 33 zx_status_t Randomize(size_t len); 34 35 // Resize the underlying buffer. If the new length is shorter, the data is truncated. If it is 36 // longer, it is padded with the given |fill| value. 37 zx_status_t Resize(size_t size, uint8_t fill = 0); 38 39 // Copies |len| bytes from |src| to |dst_off| in the underlying buffer. Resizes the buffer as 40 // needed, padding with zeros. 41 zx_status_t Copy(const void* src, size_t len, zx_off_t dst_off = 0); 42 zx_status_t Copy(const Bytes& src, zx_off_t dst_off = 0) { 43 return Copy(src.get(), src.len(), dst_off); 44 } 45 46 // Array access operators. Assert that |off| is not out of bounds. 47 const uint8_t& operator[](zx_off_t off) const; 48 uint8_t& operator[](zx_off_t off); 49 50 // Comparison operators. These are guaranteed to be constant-time. 51 bool operator==(const Bytes& other) const; 52 bool operator!=(const Bytes& other) const { return !(*this == other); } 53 54 private: 55 DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(Bytes); 56 57 // The underlying buffer. 58 fbl::unique_ptr<uint8_t[]> buf_; 59 // Length in bytes of memory currently allocated to the underlying buffer. 60 size_t len_; 61 }; 62 63 } // namespace crypto 64