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